diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..11631b74 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +.git +.github +.local +.treeseed +dist +node_modules +release-assets +artifacts +coverage +docs +tests diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 26845e58..120a5a60 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -9,7 +9,7 @@ on: type: choice options: - staging - - prod + - production action_kind: required: true default: deploy_web @@ -21,16 +21,13 @@ on: project_id: required: false type: string - preview_id: - required: false - type: string jobs: web: runs-on: ubuntu-latest permissions: contents: read - environment: ${{ inputs.environment == 'prod' && 'production' || 'staging' }} + environment: ${{ inputs.environment }} defaults: run: working-directory: docs @@ -40,12 +37,14 @@ jobs: TREESEED_CLOUDFLARE_ACCOUNT_ID: ${{ vars.TREESEED_CLOUDFLARE_ACCOUNT_ID }} TREESEED_CLOUDFLARE_PAGES_PROJECT_NAME: ${{ vars.TREESEED_CLOUDFLARE_PAGES_PROJECT_NAME || 'treeseed-admin-docs' }} TREESEED_CONTENT_BUCKET_NAME: ${{ vars.TREESEED_CONTENT_BUCKET_NAME }} + TREESEED_TEAM_ID: treeseed + TREESEED_R2_ACCESS_KEY_ID: ${{ secrets.TREESEED_R2_ACCESS_KEY_ID }} + TREESEED_R2_SECRET_ACCESS_KEY: ${{ secrets.TREESEED_R2_SECRET_ACCESS_KEY }} TREESEED_CONTENT_BUCKET_BINDING: ${{ vars.TREESEED_CONTENT_BUCKET_BINDING }} TREESEED_PROJECT_ID: ${{ inputs.project_id || vars.TREESEED_PROJECT_ID || 'admin' }} TREESEED_WORKFLOW_ACTION: ${{ inputs.action_kind }} TREESEED_WORKFLOW_ENVIRONMENT: ${{ inputs.environment }} TREESEED_WORKFLOW_PROJECT: ${{ inputs.project_id || vars.TREESEED_PROJECT_ID || 'admin' }} - TREESEED_WORKFLOW_PREVIEW_ID: ${{ inputs.preview_id }} steps: - uses: actions/checkout@v4 @@ -69,5 +68,4 @@ jobs: set -euo pipefail EXTRA_ARGS=() if [[ -n "${TREESEED_WORKFLOW_PROJECT:-}" ]]; then EXTRA_ARGS+=(--project-id "${TREESEED_WORKFLOW_PROJECT}"); fi - if [[ -n "${TREESEED_WORKFLOW_PREVIEW_ID:-}" ]]; then EXTRA_ARGS+=(--preview-id "${TREESEED_WORKFLOW_PREVIEW_ID}"); fi node ./node_modules/@treeseed/sdk/scripts/tenant-workflow-action.js --action "${TREESEED_WORKFLOW_ACTION}" --environment "${TREESEED_WORKFLOW_ENVIRONMENT}" "${EXTRA_ARGS[@]}" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 85989739..13444fd3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,32 +1,111 @@ -name: Publish TreeSeed Admin - +name: Build or Promote TreeSeed Admin Candidate on: push: - tags: - - "*.*.*" - workflow_dispatch: - + branches: [staging, main] + tags: ["*.*.*"] + paths-ignore: ['.github/workflows/publish.yml', '.github/workflows/component-revision.yml', 'scripts/release/reissue-component.ts', 'tests/contract/package/component-revision.test.ts', 'tests/contract/package/admin-package.test.ts'] jobs: - publish: - if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-') - runs-on: ubuntu-latest - permissions: - contents: write - environment: production + candidate-package: + if: github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/main' + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - uses: actions/setup-node@v4 - with: - node-version: 22 - registry-url: https://registry.npmjs.org - - run: npm run release:setup - - run: bash -lc 'npm run verify:local' - - run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Create GitHub release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh release create "${GITHUB_REF_NAME}" --generate-notes --verify-tag + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: { node-version: 24 } + - run: npm ci --workspaces=false --no-audit --no-fund + - run: npm run verify:direct + - name: Build immutable Cloudflare Pages application + run: | + npm run build:pages + test -f .treeseed/app-dist/_worker.js/index.js + test -f .treeseed/app-dist/_routes.json + mkdir -p source-assets + tar --sort=name --mtime='UTC 1970-01-01' --owner=0 --group=0 --numeric-owner \ + --create --gzip --file source-assets/admin-pages.tar.gz \ + --directory .treeseed/app-dist . + tar --list --gzip --file source-assets/admin-pages.tar.gz | grep -Fx './_worker.js/index.js' + - run: npm pack --json --ignore-scripts --pack-destination source-assets && npm sbom --sbom-format cyclonedx > source-assets/sbom.cdx.json + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: { name: "admin-source-${{ github.sha }}", path: source-assets/, if-no-files-found: error } + candidate-build: + if: github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/main' + needs: candidate-package + environment: ${{ github.ref_name == 'main' && 'production' || 'staging' }} + runs-on: ${{ matrix.runner }} + strategy: + matrix: + include: + - { arch: amd64, platform: linux/amd64, runner: ubuntu-24.04 } + - { arch: arm64, platform: linux/arm64, runner: ubuntu-24.04-arm } + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f + - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 + with: { username: "${{ vars.DOCKERHUB_USERNAME }}", password: "${{ secrets.DOCKERHUB_TOKEN }}" } + - uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 + with: { context: ., platforms: "${{ matrix.platform }}", push: true, tags: "treeseed/admin:candidate-${{ github.sha }}-${{ matrix.arch }}", sbom: true, provenance: mode=max } + candidate-seal: + if: github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/main' + needs: candidate-build + environment: ${{ github.ref_name == 'main' && 'production' || 'staging' }} + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: { node-version: 24 } + - run: npm ci --ignore-scripts --workspaces=false --no-audit --no-fund + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f + - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 + with: { username: "${{ vars.DOCKERHUB_USERNAME }}", password: "${{ secrets.DOCKERHUB_TOKEN }}" } + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 + with: { name: "admin-source-${{ github.sha }}", path: release-assets } + - name: Seal exact image and component assets + run: | + candidate="candidate-${GITHUB_SHA}" + docker buildx imagetools create -t "treeseed/admin:${candidate}" "treeseed/admin:${candidate}-amd64" "treeseed/admin:${candidate}-arm64" + export TREESEED_ADMIN_DIGEST="$(docker buildx imagetools inspect "treeseed/admin:${candidate}" --format '{{json .Manifest}}' | jq -r '.digest')" + [[ "$TREESEED_ADMIN_DIGEST" =~ ^sha256:[a-f0-9]{64}$ ]] + export TREESEED_RELEASE="$(node -p "require('./package.json').version")" TREESEED_SOURCE_COMMIT="$GITHUB_SHA" + node --import tsx scripts/create-component-release.ts + npm run release:custody -- seal release-assets/release-evidence-v1.json release-assets + npm run release:custody -- verify release-assets/release-evidence-v1.json + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: { name: "admin-candidate-${{ github.sha }}", path: release-assets/, if-no-files-found: error, retention-days: 30 } + promote: + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-24.04 + permissions: { actions: read, contents: write, id-token: write } + environment: ${{ contains(github.ref_name, '-') && 'staging' || 'production' }} + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: { fetch-depth: 0 } + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: { node-version: 24, registry-url: "https://registry.npmjs.org" } + - run: npm ci --ignore-scripts --workspaces=false --no-audit --no-fund + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f + - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 + with: { username: "${{ vars.DOCKERHUB_USERNAME }}", password: "${{ secrets.DOCKERHUB_TOKEN }}" } + - name: Download exact accepted candidate + env: { GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" } + run: | + if [[ "$GITHUB_REF_NAME" == *-* ]]; then candidate_branch=staging; else candidate_branch=main; fi + test "$(git rev-parse HEAD)" = "$(git rev-parse "origin/${candidate_branch}")" + run_id="$(gh run list --workflow publish.yml --branch "$candidate_branch" --commit "$GITHUB_SHA" --status success --limit 1 --json databaseId --jq '.[0].databaseId')" + test -n "$run_id"; gh run download "$run_id" --name "admin-candidate-${GITHUB_SHA}" --dir candidate + npm run release:check-tag; npm run release:custody -- verify candidate/release-evidence-v1.json + - id: before + run: echo "latest=$(npm view @treeseed/admin dist-tags.latest)" >> "$GITHUB_OUTPUT" + - name: Publish exact npm tarball + run: npm run release:publish -- "$(find candidate -maxdepth 1 -name '*.tgz' -print -quit)" + env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } + - name: Promote exact image manifest + run: | + identity="$(node -e "const e=require('./candidate/release-evidence-v1.json'); process.stdout.write(e.artifacts.find(x=>x.kind==='oci-image').identity)")" + digest="${identity#*@}"; docker buildx imagetools create -t "treeseed/admin:${GITHUB_REF_NAME}" "$identity" + test "$(docker buildx imagetools inspect "treeseed/admin:${GITHUB_REF_NAME}" --format '{{json .Manifest}}' | jq -r '.digest')" = "$digest" + - name: Verify npm read-back and publish unchanged assets + env: { GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}", EXPECTED_LATEST: "${{ steps.before.outputs.latest }}" } + run: | + test "$(npm view @treeseed/admin dist-tags.latest)" = "$EXPECTED_LATEST" + flags=(); if [[ "$GITHUB_REF_NAME" == *-rc.* ]]; then flags+=(--prerelease); fi + gh release create "$GITHUB_REF_NAME" candidate/* --generate-notes --verify-tag "${flags[@]}" diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 9c2357d1..6e86060a 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -2,9 +2,10 @@ name: Verify on: push: - branches: - - '**' + branches: [staging, main] + paths-ignore: ["docs/src/content/**"] pull_request: + # Required verification must also run for ancestry-only reconciliation PRs. workflow_dispatch: jobs: @@ -25,11 +26,28 @@ jobs: - name: Install dependencies timeout-minutes: 20 + env: + TREESEED_SKIP_PACKAGE_PREPARE: "1" run: npm run release:setup + - name: Download exact integrated UI package + uses: actions/download-artifact@v4 + with: + repository: treeseed-ai/ui + run-id: 36729378278 + name: ui-b0c9a2bdf1eed181950c1202a24ab3d9af012833 + github-token: ${{ github.token }} + path: .treeseed/ci-ui + + - name: Install exact integrated UI package + run: npm install --ignore-scripts --no-save --package-lock=false .treeseed/ci-ui/*.tgz + - name: Verify package run: npm run verify:direct + - name: Verify independent Cloudflare application + run: npm run build:pages + - name: Pack verified artifact run: mkdir -p artifacts && npm pack --json --ignore-scripts --pack-destination artifacts diff --git a/.gitignore b/.gitignore index de9815d6..bd345a30 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ npm-debug.log* public/books/*.md public/books/*.json public/__treeseed/*.json +public/favicon.svg .codex **/.ts-run-*.mjs .tmp-*/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..d339cc7f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,31 @@ +# Admin workspace guidance + +## CRITICAL: complete automated test coverage + +Every behavior, contract, state transition, failure path, and edge case must have automated unit, integration, and scene/guarantee-based acceptance coverage. This is mandatory for all projects, especially the capacity-provider and agent system. A behavior without all three layers is an unresolved delivery gap, not completed work. + +- Unit tests must prove exact outputs, validation, invariants, and boundary conditions. Cover valid and invalid inputs, missing/empty/malformed values, authorization denial, stale or moved refs, and every named prohibited field. +- Integration tests must exercise the real owning components and their public boundaries: handlers, provider/kernel execution, APIs, persistence, tools, and downstream consumers. Mocks, string assertions, compilation, or call-order checks alone are not integration proof. +- Coded scenes and guarantees must prove production-shaped end-to-end outcomes: exact governed artifacts and read-back, independent verification, actual usage, exactly-once settlement, and durable teardown. Use the project's existing native acceptance harness and respect package ownership; do not put TreeSeed-specific policy into product-neutral packages. +- Cover duplicate and concurrent execution, idempotency, partial failure, interruption, retry, resume, cancellation, expiry, provider/tool/subprocess errors, unsafe commands, and cleanup without residue. Preserve failed observations; do not fabricate dispositions, usage, citations, receipts, or passing replays. +- For every defect, first add a focused regression that reproduces the failure, then add or strengthen the corresponding integration and scene/guarantee cases. Fix the earliest owning contract. Retain previously covered behavior and all historical failed evidence. +- Never weaken assertions, remove negative cases, narrow acceptance criteria, disable type checks, extend deadlines, increase allowances, or relabel failures as passes to get green results. An unexpected agent timeout is a fatal architecture defect: agents must check authoritative remaining time frequently, reserve verification/closeout time, and produce authorized continuation proposals for unfinished work before the original deadline. +- Delivery requires passing evidence at all three layers on the exact candidate. Missing environments, credentials, skipped tests, or blocked layers remain explicitly unproven. Component passes, suite totals, line coverage, and process completion never substitute for full semantic acceptance. +- Before EVERY acceptance run (scene or guarantee), run ALL automated unit and integration tests for every participating project on the exact candidate. Focused regressions are additional checks, not substitutes for the complete suites. Failed, skipped, missing, empty, or inconclusive prerequisite coverage blocks acceptance; never launch a live campaign first and discover prerequisite failures afterward. Run the complete suites once per participating project per acceptance invocation, before any scene begins; do not reuse a previous invocation's passing receipt or omit tests to save time. Preserve exact command, candidate, run, and result evidence in the existing Issue and Actions artifacts. +- Keep the behavior-to-unit/integration/scene mapping and exact command, commit, run, and artifact evidence in the existing Issue body and Actions artifacts. Reproduce failures with cheap focused tests before another expensive activation or full campaign; batch known fixes, inspect failed jobs, and reuse only unchanged immutable evidence. No duplicate campaigns or new coverage side channels. + +## Agent configuration and handler ownership + +When this project defines or consumes agents, agent identity, task instructions, prompts, capabilities, permissions, parameters, and activity profiles must be governed YAML configuration. Adding or renaming an agent using existing handlers must not require provider, guest, kernel, or scheduler code changes. Do not hardcode named-role configuration in shared runtime code; shared rules must apply to any configured agent. + +Task-specific executable code belongs in the configured handler. Reuse existing class-based handlers and exact profile bindings; new coded functionality may require a pinned handler, but not a parallel dispatch path or duplicated policy. Test arbitrary YAML-defined agents, renamed identities, handler selection, changed prompts/parameters, denied permissions, and unknown/duplicate handlers through unit, real integration, and coded acceptance cases. + +Preserve the independent Admin package build and access-controlled project knowledge surfaces. + +## Branch and deployment boundary + +`main` is the only production branch and maps only to the `production` deployment environment. `staging` is the only development-integration branch and maps only to the `staging` deployment environment. Short-lived pull-request branches may validate without deploying, but they must never define another deployment environment. Do not create or use `development`, `preview`, `stable`, or any other GitHub deployment environment; preview deployments are prohibited. Release tags may promote an exact reviewed `staging` commit to `production` without creating another branch or environment. Artifact channel names must never become GitHub deployment environments. + +## Project library + +Use `trsd library show admin` and `status` before querying `treeseed-ai/admin-library`. Read root-level paths at an exact commit. Author only through governed library workspaces and reviews. Never recreate a library `src/content` tree or edit `.treeseed/data` directly. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..ac997a2e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM node:22-bookworm-slim AS build +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci --ignore-scripts +COPY . . +ENV TREESEED_WEB_RUNTIME_TARGET=managed-node +RUN npm run build +RUN npm prune --omit=dev --ignore-scripts + +FROM node:22-bookworm-slim AS runtime +WORKDIR /app +ENV NODE_ENV=production HOST=0.0.0.0 PORT=4322 +COPY --from=build /app/.treeseed/app-dist ./app +COPY --from=build /app/node_modules ./node_modules +COPY --from=build /app/package.json ./package.json +EXPOSE 4322 +CMD ["node", "./app/server/entry.mjs"] diff --git a/README.md b/README.md index 7b70b3db..11943849 100644 --- a/README.md +++ b/README.md @@ -1,184 +1,46 @@ # @treeseed/admin -`@treeseed/admin` is the distributable Treeseed administration portal for organizations. It gives a Treeseed site the authenticated admin surfaces for teams, projects, hosts, work, knowledge, catalog browsing, operational status, and secret-manager workflows. +TreeSeed's independently deployable administration application and reusable route package. Admin manages teams, projects, capacity, AI, work, knowledge, service connections, and application profiles. Market remains independently built and deployed. -Use this package when you want a Treeseed-compatible admin portal without taking on the Treeseed market site's public messaging, buyer checkout, or backend ecommerce implementation. - -## What You Can Build With Admin - -- Internal administration portals for teams and projects -- Host and credential management surfaces -- Knowledge and work management screens -- Operational status and deployment control surfaces -- Agent capacity allocation, provider session, assignment, mode-run, and usage views over API contracts -- Catalog/profile browsing and seller commerce operations without buyer payment processing -- Seller readiness, ecommerce monitoring, product governance, scoped-service operations, capacity listing review, and Commons steward operations through API facades -- Admin integrations that can be layered into a host Treeseed site - -Admin is not a UI component library. Reusable layout-down components and styles live in `@treeseed/ui`. - -## Install +## Build and run ```bash -npm install @treeseed/admin @treeseed/core @treeseed/ui @treeseed/sdk -``` - -The host application owns deployment and site configuration. In this workspace, the root `@treeseed/market` app is that host. - -## Use In A Treeseed Site - -Add the admin plugin to the host site's `treeseed.site.yaml`: - -```yaml -plugins: - - package: "@treeseed/core/plugin-default" - - package: "@treeseed/admin/plugin" -``` - -Use the admin Astro config helper from the host app: - -```ts -import { defineTreeseedAdminConfig } from '@treeseed/admin/config'; - -export default defineTreeseedAdminConfig(); -``` - -Delegate middleware from the host app: - -```ts -export { onRequest } from '@treeseed/admin/middleware'; -``` - -## Required Host App Setup - -The host app must provide: - -- a host-owned `treeseed.site.yaml` when the app owns a deployable runtime surface -- tenant config and environment values -- public content and page overrides -- deployment target and hosting workflow -- API base URL or `/v1/*` proxy path -- any tenant-specific branding or marketplace policy - -`@treeseed/admin` does not ship a package-local `treeseed.site.yaml` and does not own hosting. The root Market app owns the Treeseed web tenant in this workspace; other packages may own package-local manifests only when they operate independently released runtime surfaces. - -## Routes And Capabilities - -Admin contributes route metadata through: - -```ts -import { ADMIN_ROUTES } from '@treeseed/admin/routes'; -``` - -The route set includes admin application pages, auth pages, team invite acceptance, API proxy route metadata, and generic catalog/profile browsing surfaces. Host apps can override Astro pages through their normal Treeseed page override mechanism. - -Admin route composition follows the current TreeSeed shell model: - -- `/app/**` pages use `TreeseedAppLayout`, which composes the UI shell primitives for authenticated app work. -- `/market/**` acquisition/catalog pages use `TreeseedOperationalMarketLayout`, the authenticated operational market shell. -- `/auth/**` pages use UI `AuthShell`. -- `/u/**`, `/t/**`, `/p/**`, and invite acceptance pages use public/auth-appropriate layouts and must not show app team operations. - -`ProductShell` and `PublicShell` are compatibility wrappers in `@treeseed/ui`; Admin pages should use the package layouts above rather than importing those wrappers directly. - -## Auth And Sessions - -Admin owns reusable browser auth/session flow, callback handling, account/profile UX integration, and middleware composition. Backend service trust, persistent auth storage, and service credential validation belong in `@treeseed/api`. - -Host apps provide deployment-specific secrets and provider settings through their environment registry and secret manager. - -## API Connection - -Admin reaches backend behavior through API client facades and HTTP/proxy surfaces. It must not import backend implementation from `@treeseed/api`. - -In the root market app, `/v1/*` is the web proxy to the API service hosted from `packages/api`. - -## Secret Manager Support - -Admin owns the user-facing secret-manager experience: - -- provider selection -- host credential forms -- unlock/passphrase UX -- linked manager status -- diagnostics views - -The public contract is exported from: - -```ts -import type { TreeseedSecretManagerProvider } from '@treeseed/admin/secret-managers'; -``` - -Provider mutation, secure read/write adapters, import/adopt/reconcile behavior, and target-specific sync belong in SDK/API primitives. - -## Agent Capacity Surfaces - -Admin may expose allocation-set editing, project/agent-class capacity views, planning/acting splits, provider registration, provider availability sessions, assignment status, mode-run timelines, usage summaries, and blocker diagnostics. - -The current capacity operator surfaces are: - -- `/app/capacity/allocation` for portfolio and project agent-class allocation. -- `/app/capacity/providers` for provider registration, native capacity, grants, and lifecycle overview. -- `/app/capacity/runtime` for read-only allocation-set versions, project agent classes, provider sessions, accepted capacity plans, synthesized or explicit assignments, assignment source/explanation metadata, and mode-run telemetry. The API facade also exposes decision readiness, execution inputs, capacity plans, and workday settlement summaries for focused operator drill-downs. - -Admin does not own scheduling, assignment selection, provider runtime internals, or ledger settlement. Those belong to API, agent runtime, and SDK contracts as described in the root [Agent Capacity Operator Surfaces](../../docs/agent-capacity-operator-surfaces.md) guide. - -## Commerce Operations Without Buyer Checkout - -Admin can display and operate seller-side commerce records through API client facades: vendor readiness, product registry state, offer/price review, sales summaries, refunds, fulfillment, cooperative ownership workflows, scoped service requests, capacity listing inquiries, seller monitoring, and Commons steward decisions. - -The extension contract is exported from: - -```ts -import type { AdminCommerceProvider } from '@treeseed/admin/commerce'; +npm ci +npm run dev +npm run build:app +npm run build:pages +npm run release:verify ``` -Admin does not implement Stripe Elements, checkout confirmation, Stripe Checkout Sessions, PaymentIntent creation, webhooks, invoices, buyer subscriptions UI, seller payouts, commissions, application fees, revenue splits, benefit payout allocation, capacity billing, provider execution, marketplace grants/reservations, or routing decisions. Authenticated operational buyer checkout and participant marketplace flows belong in the root market app. Backend state and Stripe server calls belong in `@treeseed/api`. +The Node and Cloudflare applications use the same package-owned Identity integration. The npm library is emitted under `dist`; the hosted application is emitted under `.treeseed/app-dist`. -## Extension Points +## Identity configuration -Public exports include: +Deployment supplies these runtime settings, separately from source configuration: -- `@treeseed/admin` -- `@treeseed/admin/config` -- `@treeseed/admin/content-config` -- `@treeseed/admin/plugin` -- `@treeseed/admin/routes` -- `@treeseed/admin/middleware` -- `@treeseed/admin/commerce` -- `@treeseed/admin/secret-managers` -- `@treeseed/admin/lib/*` -- `@treeseed/admin/view-models/*` +| Setting | Purpose | +| --- | --- | +| `TREESEED_SITE_URL` | This application's HTTPS origin | +| `TREESEED_API_BASE_URL` | The exact HTTPS API resource | +| `TREESEED_IDENTITY_ISSUER` | The explicitly selected, API-advertised issuer | +| `TREESEED_IDENTITY_ACCOUNT_URL` | That authority's HTTPS account-management page | +| `TREESEED_IDENTITY_WORKLOAD_CLIENT_ID` | This application's independent workload client | +| `TREESEED_IDENTITY_WORKLOAD_PRIVATE_KEY` | Protected PKCS8 asymmetric workload key, never browser configuration | -Use package exports only. Do not import from `packages/admin/src` in host applications. +The API must register the application's browser client and exact `/auth/callback` redirect, and authorize its workload client for the SDK's browser-session bridge scope and permission. The browser and workload clients are distinct. Production must not select this artifact before the coordinated API, Identity, database, and Deployment migration passes. -## What Admin Does Not Own +Sign-in redirects to Identity; Admin never collects a login password, issues access tokens, or stores refresh tokens in browser cookies. The shared Identity adapter sends opaque, host-only, Secure/HttpOnly application handles to the browser. API stores encrypted one-use PKCE transactions and session credentials. Resource-bound access tokens exist only on the server and are never serialized into Astro locals. -- reusable UI primitives or CSS tokens; use `@treeseed/ui` -- generic Astro/Starlight runtime; use `@treeseed/core` -- backend API implementation, PostgreSQL, migrations, or operations runner; use `@treeseed/api` -- capacity provider runtime; use `@treeseed/agent` -- buyer checkout, Stripe Elements, payout/commission logic, capacity execution, or backend ecommerce policy; use root market for authenticated operational marketplace/cart/checkout/service/capacity/Commons surfaces and `@treeseed/api` for backend state -- TreeDX repository service internals -- host app deployment manifest +Profile and contact-email changes remain API-owned application operations. Confirming a contact email does not link sign-in identities or grant team membership. Passwords, MFA, and recovery are managed at the configured Identity account page. App logout revokes this application session; it does not silently terminate other applications' identity sessions. -## Verification And Release +Applications need independent browser clients, workload clients, and cookies. Never copy these credentials to another Market API or forward one resource's bearer token to another. There is no fallback to legacy password, shared-secret assertion, or access-token-cookie authentication. -Package commands: +## Composition -```bash -npm install -npm run build -npm run verify:local -npm run release:verify -``` +Install `@treeseed/admin`, `@treeseed/core`, `@treeseed/ui`, and `@treeseed/sdk`; add `@treeseed/admin/plugin` to the host site declaration and delegate middleware to `@treeseed/admin/middleware`. Public exports are authoritative in `package.json`. Reusable forms and account components belong to UI; backend access remains HTTP through the configured API, not imported API implementation. -Release integration: +## Acceptance ownership -- `treeseed.package.yaml` declares the package repository and release gate. -- `deploy.yml` is the hosted release gate workflow. -- `publish.yml` publishes semver tags to npm. -- GitHub repository credential: `TREESEED_GITHUB_TOKEN_TREESEED_AI_ADMIN`. -- GitHub `production` environment secret: `NPM_TOKEN`. +Admin retains application sign-in/callback/logout and contact-email scenarios. Registration and password recovery belong to Identity and its managed Deployment acceptance, not duplicate Admin forms. The login scene requires a disposable Identity account and explicit API principal mapping; its fixture password is test-only. Unit contracts are not a substitute for that managed browser acceptance. -See the root [Package Ownership](../../docs/package-ownership.md) guide for cross-package boundaries. +Changes ship through Issues, PRs, Actions, staging candidates, and exact Platform composition. Human review is reserved for production PRs to `main`. Rollback requires a coordinated application/database restore point; never run an old authentication writer against migrated data. diff --git a/astro.config.ts b/astro.config.ts new file mode 100644 index 00000000..8606a070 --- /dev/null +++ b/astro.config.ts @@ -0,0 +1,35 @@ +import { dirname, resolve } from 'node:path'; +import { realpathSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { sourceUpdates } from './scripts/development/source-updates'; + +const tenantRoot = dirname(fileURLToPath(import.meta.url)); +process.env.TREESEED_TENANT_ROOT = tenantRoot; +process.chdir(tenantRoot); + +const { createTenantSite } = await import('@treeseed/core/config'); +const site = createTenantSite(); +const developmentWorkspaceRoot = process.env.TREESEED_DEVELOPMENT_WORKSPACE_ROOT?.trim(); +const aliases = site.vite?.resolve?.alias ?? []; +const existingAliases = Array.isArray(aliases) ? aliases : Object.entries(aliases).map(([find, replacement]) => ({find, replacement})); + +export default { + ...site, + devToolbar: { enabled: false }, + vite: {...site.vite, plugins: [...(site.vite?.plugins ?? []), sourceUpdates(false)]}, + ...(developmentWorkspaceRoot ? { + vite: { + ...site.vite, + plugins: [...(site.vite?.plugins ?? []), sourceUpdates(process.env.TREESEED_DEVELOPMENT_MODE === 'live')], + resolve: { ...site.vite?.resolve, preserveSymlinks: true, dedupe: [...(site.vite?.resolve?.dedupe ?? []), '@treeseed/ui'], + alias: [{find: '@treeseed/ui/forms/client', replacement: realpathSync(resolve(tenantRoot, 'node_modules/@treeseed/ui/dist/forms-client.js'))}, ...existingAliases] }, + ssr: { ...site.vite?.ssr, noExternal: ['@treeseed/ui'] }, + server: { + ...site.vite?.server, + allowedHosts: ['admin.treeseed.localhost'], + fs: { ...site.vite?.server?.fs, allow: [...(site.vite?.server?.fs?.allow ?? []), developmentWorkspaceRoot] }, + }, + }, + } : {}), + outDir: '.treeseed/app-dist', +}; diff --git a/compose.development.yml b/compose.development.yml new file mode 100644 index 00000000..e14e391f --- /dev/null +++ b/compose.development.yml @@ -0,0 +1,64 @@ +services: + admin-live: + image: node:24-bookworm-slim + working_dir: ${TREESEED_DEVELOPMENT_WORKTREE:?TreeSeed development worktree is required} + init: true + read_only: true + command: ["node", "--import", "tsx", "scripts/development/live-web.ts"] + environment: + HOST: 0.0.0.0 + PORT: "4322" + HOME: /tmp/treeseed-admin-home + NODE_ENV: + NODE_EXTRA_CA_CERTS: + __VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS: admin.treeseed.localhost + TREESEED_WEB_RUNTIME_TARGET: managed-node + TREESEED_API_BASE_URL: + TREESEED_API_AUDIENCE: + TREESEED_API_CA_FILE: + TREESEED_API_CREDENTIAL_FILE: + TREESEED_SITE_URL: + TREESEED_REVIEWER_URL: + TREESEED_AUTH_MODE: + TREESEED_AUTH_INTERNAL_SIGNUP: + TREESEED_AUTH_EMAIL_FROM: + TREESEED_AUTH_EMAIL_REPLY_TO: + TREESEED_AUTH_EMAIL_VERIFICATION_ENABLED: + TREESEED_BETTER_AUTH_SECRET: + TREESEED_WEB_SERVICE_ID: + TREESEED_WEB_SERVICE_SECRET: + TREESEED_WEB_ASSERTION_SECRET: + TREESEED_WEB_CSRF_SECRET: + TREESEED_MAILPIT_SMTP_HOST: + TREESEED_MAILPIT_SMTP_PORT: + TREESEED_DEVELOPMENT_SESSION_ID: + TREESEED_DEVELOPMENT_MODE: + TREESEED_DEVELOPMENT_WORKSPACE_ROOT: + TREESEED_DEVELOPMENT_WORKTREE: + ports: + - "127.0.0.1:4322:4322" + volumes: + - ${TREESEED_DEVELOPMENT_WORKSPACE_ROOT:?TreeSeed development workspace root is required}:${TREESEED_DEVELOPMENT_WORKSPACE_ROOT:?TreeSeed development workspace root is required}:ro + - /etc/treeseed/cli/localhost-ca.crt:/etc/treeseed/cli/localhost-ca.crt:ro + tmpfs: + - /tmp + - ${TREESEED_DEVELOPMENT_WORKTREE:?TreeSeed development worktree is required}/.astro + - ${TREESEED_DEVELOPMENT_WORKTREE:?TreeSeed development worktree is required}/node_modules/.astro + - ${TREESEED_DEVELOPMENT_WORKTREE:?TreeSeed development worktree is required}/node_modules/.vite + networks: + - edge + - platform + healthcheck: + test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:4322/healthz').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"] + interval: 2s + timeout: 3s + retries: 60 + stop_grace_period: 15s + +networks: + edge: + external: true + name: treeseed-edge + platform: + external: true + name: treeseed-platform diff --git a/deploy/compose.template.yml b/deploy/compose.template.yml new file mode 100644 index 00000000..6a3d8af8 --- /dev/null +++ b/deploy/compose.template.yml @@ -0,0 +1,31 @@ +services: + admin: + image: "@ADMIN_IMAGE@" + restart: unless-stopped + env_file: /etc/treeseed/components/admin/environment + environment: + HOST: 0.0.0.0 + PORT: "4322" + TREESEED_WEB_RUNTIME_TARGET: managed-node + NODE_EXTRA_CA_CERTS: /run/treeseed/identity/ca.crt + extra_hosts: + - "${TREESEED_IDENTITY_HOSTNAME:?Managed Identity hostname required}:host-gateway" + - "${TREESEED_API_HOSTNAME:?Managed API hostname required}:host-gateway" + volumes: + - type: bind + source: /etc/treeseed/cli/localhost-ca.crt + target: /run/treeseed/identity/ca.crt + read_only: true + networks: [platform, treeseed-edge] + healthcheck: + test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:4322/healthz').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"] + interval: 10s + timeout: 3s + retries: 12 +networks: + platform: + name: treeseed-platform + external: true + treeseed-edge: + name: treeseed-edge + external: true diff --git a/docs/astro.config.ts b/docs/astro.config.ts index 5570b541..5deeb78b 100644 --- a/docs/astro.config.ts +++ b/docs/astro.config.ts @@ -3,6 +3,6 @@ import { fileURLToPath } from 'node:url'; process.env.TREESEED_TENANT_ROOT ??= dirname(fileURLToPath(import.meta.url)); -const { createTreeseedTenantSite } = await import('@treeseed/core/config'); +const { createTenantSite } = await import('@treeseed/core/config'); -export default createTreeseedTenantSite(); +export default createTenantSite(); diff --git a/docs/src/config.yaml b/docs/src/config.yaml index 94419c35..ec4fa68c 100644 --- a/docs/src/config.yaml +++ b/docs/src/config.yaml @@ -3,7 +3,7 @@ site: src: https://treeseed.ai/logo.svg alt: TreeSeed admin Knowledge Hub logo name: TreeSeed Admin Knowledge Hub - statement: TreeSeed Admin package knowledge, agents, and workday memory + statement: Grow what you know siteUrl: https://admin.treeseed.ai githubRepository: https://github.com/treeseed-ai/admin discordLink: https://discord.gg/example @@ -48,33 +48,33 @@ models: defaults: author: TreeSeed Admin Team draft: false - tags: [] + groupIds: [] questions: defaults: draft: false - tags: [] + groupIds: [] objectives: defaults: draft: false - tags: [] + groupIds: [] proposals: defaults: draft: false - tags: [] + groupIds: [] decisions: defaults: draft: false - tags: [] + groupIds: [] people: defaults: status: live - tags: [] + groupIds: [] agents: defaults: - tags: [] + groupIds: [] books: defaults: - tags: [] + groupIds: [] docs: defaults: - tags: [] + groupIds: [] diff --git a/docs/src/content.config.ts b/docs/src/content.config.ts index dbbc8749..8d960e49 100644 --- a/docs/src/content.config.ts +++ b/docs/src/content.config.ts @@ -4,6 +4,6 @@ import { fileURLToPath } from 'node:url'; const tenantRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..'); process.env.TREESEED_TENANT_ROOT ??= tenantRoot; -const { createTreeseedTenantCollections } = await import('@treeseed/core/content-config'); +const { createTenantCollections } = await import('@treeseed/core/content-config'); -export const collections = createTreeseedTenantCollections(); +export const collections = createTenantCollections(); diff --git a/docs/src/content/agents/architect.mdx b/docs/src/content/agents/architect.mdx deleted file mode 100644 index c58beacc..00000000 --- a/docs/src/content/agents/architect.mdx +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: agent:architect -slug: architect -title: Architect -name: Architect -agentClass: architecture -projectAgentClassId: architecture -projectAgentClassSlug: architecture -template: engineering-agent/architect -enabled: true -description: Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. -summary: Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. -runtimeStatus: active -tags: - - agent - - engineering-team - - architecture -identity: - purpose: Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: architecture.planning - description: Planning support for architecture. - produces: - - question - - note - - proposal_feedback - - id: architecture.execute - description: Assignment execution support for architecture. - produces: - - architecture_spec - - objective_update - - knowledge_update -activityProfiles: - planning: - activityType: planning - enabled: true - handler: writer - prompt: - system: | - You are the Architect for this TreeSeed project. Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: planning - branchPolicy: - kind: staging-content - base: staging - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - linked_note:create - - proposal_feedback:create - - question:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - estimating: - activityType: estimating - enabled: true - handler: estimate - prompt: - system: | - You are the Architect for this TreeSeed project. Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: estimating - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - estimate:create - - dependency_declaration:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - reviewing: - activityType: reviewing - enabled: true - handler: writer - prompt: - system: | - You are the Architect for this TreeSeed project. Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reviewing - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - acting: - activityType: acting - enabled: true - handler: writer - prompt: - system: | - You are the Architect for this TreeSeed project. Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting - branchPolicy: - kind: staging-content - base: staging - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - architecture_spec:create - - objective_update:create - - knowledge_update:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false ---- - -Architect for the admin TreeSeed project. - -Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. diff --git a/docs/src/content/agents/engineer.mdx b/docs/src/content/agents/engineer.mdx deleted file mode 100644 index ee9e3137..00000000 --- a/docs/src/content/agents/engineer.mdx +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: agent:engineer -slug: engineer -title: Engineer -name: Engineer -agentClass: engineering -projectAgentClassId: engineering -projectAgentClassSlug: engineering -template: engineering-agent/engineer -enabled: true -description: Implements decision-scoped code and configuration changes without modifying tests. -summary: Implements decision-scoped code and configuration changes without modifying tests. -runtimeStatus: active -tags: - - agent - - engineering-team - - engineering -identity: - purpose: Implements decision-scoped code and configuration changes without modifying tests. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: engineering.planning - description: Planning support for engineering. - produces: - - question - - note - - proposal_feedback - - id: engineering.execute - description: Assignment execution support for engineering. - produces: - - implementation-change - - implementation_report -activityProfiles: - planning: - activityType: planning - enabled: true - handler: actor - prompt: - system: | - You are the Engineer for this TreeSeed project. Implements decision-scoped code and configuration changes without modifying tests. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: planning - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - linked_note:create - - proposal_feedback:create - - question:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: true - estimating: - activityType: estimating - enabled: true - handler: estimate - prompt: - system: | - You are the Engineer for this TreeSeed project. Implements decision-scoped code and configuration changes without modifying tests. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: estimating - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - estimate:create - - dependency_declaration:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - reviewing: - activityType: reviewing - enabled: true - handler: writer - prompt: - system: | - You are the Engineer for this TreeSeed project. Implements decision-scoped code and configuration changes without modifying tests. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reviewing - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - acting: - activityType: acting - enabled: true - handler: actor - prompt: - system: | - You are the Engineer for this TreeSeed project. Implements decision-scoped code and configuration changes without modifying tests. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting - branchPolicy: - kind: assignment-feature - base: staging - target: staging - branchNameTemplate: agent/{agentSlug}/{assignmentId} - worktree: new - updateBaseBeforeRun: true - mergeTargetBeforeSave: true - prefix: engineer - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - - treeseed.changed_paths - - treeseed.verify - - treeseed.dev_plan - outputs: - messageTypes: [] - modelMutations: - - implementation-change:create - - implementation_report:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: true ---- - -Engineer for the admin TreeSeed project. - -Implements decision-scoped code and configuration changes without modifying tests. diff --git a/docs/src/content/agents/releaser.mdx b/docs/src/content/agents/releaser.mdx deleted file mode 100644 index c526f6ea..00000000 --- a/docs/src/content/agents/releaser.mdx +++ /dev/null @@ -1,334 +0,0 @@ ---- -id: agent:releaser -slug: releaser -title: Releaser -name: Releaser -agentClass: release -projectAgentClassId: release -projectAgentClassSlug: release -template: engineering-agent/releaser -enabled: true -description: Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. -summary: Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. -runtimeStatus: active -tags: - - agent - - engineering-team - - release -identity: - purpose: Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: release.planning - description: Planning support for release. - produces: - - question - - note - - proposal_feedback - - id: release.execute - description: Assignment execution support for release. - produces: - - release_report - - release_readiness -activityProfiles: - planning: - activityType: planning - enabled: true - handler: releaser - prompt: - system: | - You are the Releaser for this TreeSeed project. Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: planning - branchPolicy: - kind: staging-release - base: staging - target: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - - treeseed.changed_paths - - treeseed.verify - - treeseed.dev_plan - outputs: - messageTypes: [] - modelMutations: - - linked_note:create - - proposal_feedback:create - - question:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - estimating: - activityType: estimating - enabled: true - handler: estimate - prompt: - system: | - You are the Releaser for this TreeSeed project. Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: estimating - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - estimate:create - - dependency_declaration:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - reviewing: - activityType: reviewing - enabled: true - handler: writer - prompt: - system: | - You are the Releaser for this TreeSeed project. Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reviewing - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - acting: - activityType: acting - enabled: true - handler: releaser - prompt: - system: | - You are the Releaser for this TreeSeed project. Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting - branchPolicy: - kind: staging-release - base: staging - target: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - - treeseed.changed_paths - - treeseed.verify - - treeseed.dev_plan - outputs: - messageTypes: [] - modelMutations: - - release_report:create - - release_readiness:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: team-human - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false ---- - -Releaser for the admin TreeSeed project. - -Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. diff --git a/docs/src/content/agents/reporter.mdx b/docs/src/content/agents/reporter.mdx deleted file mode 100644 index 9bec2f43..00000000 --- a/docs/src/content/agents/reporter.mdx +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: agent:reporter -slug: reporter -title: Reporter -name: Reporter -agentClass: reporting -projectAgentClassId: reporting -projectAgentClassSlug: reporting -template: engineering-agent/reporter -enabled: true -description: Deterministically summarizes workdays, capacity, graph progress, blockers, tool telemetry, and outcomes. -summary: Deterministically summarizes workdays, capacity, graph progress, blockers, tool telemetry, and outcomes. -runtimeStatus: active -tags: - - agent - - engineering-team - - reporting -identity: - purpose: Deterministically summarizes workdays, capacity, graph progress, blockers, tool telemetry, and outcomes. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: reporting.planning - description: Planning support for reporting. - produces: - - question - - note - - proposal_feedback - - id: reporting.execute - description: Assignment execution support for reporting. - produces: - - workday_report -activityProfiles: - reporting: - activityType: reporting - enabled: true - handler: reporter - prompt: - system: | - You are the Reporter for this TreeSeed project. Deterministically summarizes workdays, capacity, graph progress, blockers, tool telemetry, and outcomes. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reporting - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - workday_report:create - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false ---- - -Reporter for the admin TreeSeed project. - -Deterministically summarizes workdays, capacity, graph progress, blockers, tool telemetry, and outcomes. diff --git a/docs/src/content/agents/researcher.mdx b/docs/src/content/agents/researcher.mdx deleted file mode 100644 index 25183f76..00000000 --- a/docs/src/content/agents/researcher.mdx +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: agent:researcher -slug: researcher -title: Researcher -name: Researcher -agentClass: research -projectAgentClassId: research -projectAgentClassSlug: research -template: engineering-agent/researcher -enabled: true -description: Answers questions and improves project knowledge through TreeDX-backed research content. -summary: Answers questions and improves project knowledge through TreeDX-backed research content. -runtimeStatus: active -tags: - - agent - - engineering-team - - research -identity: - purpose: Answers questions and improves project knowledge through TreeDX-backed research content. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: research.planning - description: Planning support for research. - produces: - - question - - note - - proposal_feedback - - id: research.execute - description: Assignment execution support for research. - produces: - - question_answer - - knowledge_update - - linked_note -activityProfiles: - planning: - activityType: planning - enabled: true - handler: writer - prompt: - system: | - You are the Researcher for this TreeSeed project. Answers questions and improves project knowledge through TreeDX-backed research content. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: planning - branchPolicy: - kind: main-planning-content - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - linked_note:create - - proposal_feedback:create - - question:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - estimating: - activityType: estimating - enabled: true - handler: estimate - prompt: - system: | - You are the Researcher for this TreeSeed project. Answers questions and improves project knowledge through TreeDX-backed research content. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: estimating - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - estimate:create - - dependency_declaration:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - reviewing: - activityType: reviewing - enabled: true - handler: writer - prompt: - system: | - You are the Researcher for this TreeSeed project. Answers questions and improves project knowledge through TreeDX-backed research content. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reviewing - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - acting: - activityType: acting - enabled: true - handler: writer - prompt: - system: | - You are the Researcher for this TreeSeed project. Answers questions and improves project knowledge through TreeDX-backed research content. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting - branchPolicy: - kind: main-planning-content - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - question_answer:create - - knowledge_update:create - - linked_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false ---- - -Researcher for the admin TreeSeed project. - -Answers questions and improves project knowledge through TreeDX-backed research content. diff --git a/docs/src/content/agents/reviewer.mdx b/docs/src/content/agents/reviewer.mdx deleted file mode 100644 index c41b0d40..00000000 --- a/docs/src/content/agents/reviewer.mdx +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: agent:reviewer -slug: reviewer -title: Reviewer -name: Reviewer -agentClass: review -projectAgentClassId: review -projectAgentClassSlug: review -template: engineering-agent/reviewer -enabled: true -description: Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. -summary: Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. -runtimeStatus: active -tags: - - agent - - engineering-team - - review -identity: - purpose: Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: review.planning - description: Planning support for review. - produces: - - question - - note - - proposal_feedback - - id: review.execute - description: Assignment execution support for review. - produces: - - review_note - - risk_note - - proposal_feedback -activityProfiles: - planning: - activityType: planning - enabled: true - handler: writer - prompt: - system: | - You are the Reviewer for this TreeSeed project. Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: planning - branchPolicy: - kind: main-planning-content - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - linked_note:create - - proposal_feedback:create - - question:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - estimating: - activityType: estimating - enabled: true - handler: estimate - prompt: - system: | - You are the Reviewer for this TreeSeed project. Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: estimating - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - estimate:create - - dependency_declaration:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - reviewing: - activityType: reviewing - enabled: true - handler: writer - prompt: - system: | - You are the Reviewer for this TreeSeed project. Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reviewing - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - acting: - activityType: acting - enabled: true - handler: writer - prompt: - system: | - You are the Reviewer for this TreeSeed project. Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting - branchPolicy: - kind: main-planning-content - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - - proposal_feedback:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false ---- - -Reviewer for the admin TreeSeed project. - -Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. diff --git a/docs/src/content/agents/technical-writer.mdx b/docs/src/content/agents/technical-writer.mdx deleted file mode 100644 index 3c42c337..00000000 --- a/docs/src/content/agents/technical-writer.mdx +++ /dev/null @@ -1,326 +0,0 @@ ---- -id: agent:technical-writer -slug: technical-writer -title: Technical Writer -name: Technical Writer -agentClass: technical-writing -projectAgentClassId: technical-writing -projectAgentClassSlug: technical-writing -template: engineering-agent/technical-writer -enabled: true -description: Maintains user, developer, and operator documentation for released and staged project capabilities. -summary: Maintains user, developer, and operator documentation for released and staged project capabilities. -runtimeStatus: active -tags: - - agent - - engineering-team - - technical-writing -identity: - purpose: Maintains user, developer, and operator documentation for released and staged project capabilities. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: technical-writing.planning - description: Planning support for technical-writing. - produces: - - question - - note - - proposal_feedback - - id: technical-writing.execute - description: Assignment execution support for technical-writing. - produces: - - documentation_update - - knowledge_update -activityProfiles: - planning: - activityType: planning - enabled: true - handler: writer - prompt: - system: | - You are the Technical Writer for this TreeSeed project. Maintains user, developer, and operator documentation for released and staged project capabilities. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: planning - branchPolicy: - kind: staging-content - base: staging - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - linked_note:create - - proposal_feedback:create - - question:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - estimating: - activityType: estimating - enabled: true - handler: estimate - prompt: - system: | - You are the Technical Writer for this TreeSeed project. Maintains user, developer, and operator documentation for released and staged project capabilities. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: estimating - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - estimate:create - - dependency_declaration:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - reviewing: - activityType: reviewing - enabled: true - handler: writer - prompt: - system: | - You are the Technical Writer for this TreeSeed project. Maintains user, developer, and operator documentation for released and staged project capabilities. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reviewing - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - acting: - activityType: acting - enabled: true - handler: writer - prompt: - system: | - You are the Technical Writer for this TreeSeed project. Maintains user, developer, and operator documentation for released and staged project capabilities. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting - branchPolicy: - kind: staging-content - base: staging - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - outputs: - messageTypes: [] - modelMutations: - - documentation_update:create - - knowledge_update:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false ---- - -Technical Writer for the admin TreeSeed project. - -Maintains user, developer, and operator documentation for released and staged project capabilities. diff --git a/docs/src/content/agents/tester.mdx b/docs/src/content/agents/tester.mdx deleted file mode 100644 index 3a845d3d..00000000 --- a/docs/src/content/agents/tester.mdx +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: agent:tester -slug: tester -title: Tester -name: Tester -agentClass: testing -projectAgentClassId: testing -projectAgentClassSlug: testing -template: engineering-agent/tester -enabled: true -description: Creates tests before implementation and verifies behavior without modifying implementation code. -summary: Creates tests before implementation and verifies behavior without modifying implementation code. -runtimeStatus: active -tags: - - agent - - engineering-team - - testing -identity: - purpose: Creates tests before implementation and verifies behavior without modifying implementation code. - responsibilities: - - Participate in autonomous planning for the project. - - Submit structured estimates when assigned estimating work. - - Use only profile-scoped tools and TreeDX-backed content operations. - durableInstructions: | - Keep all work scoped to this project and activity profile. Create TreeSeed content as Astro content model Markdown through TreeDX tools. Ask questions through TreeDX question content when blocked. -capabilities: - - id: testing.planning - description: Planning support for testing. - produces: - - question - - note - - proposal_feedback - - id: testing.execute - description: Assignment execution support for testing. - produces: - - test-suite - - test_report -activityProfiles: - planning: - activityType: planning - enabled: true - handler: actor - prompt: - system: | - You are the Tester for this TreeSeed project. Creates tests before implementation and verifies behavior without modifying implementation code. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: planning - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - linked_note:create - - proposal_feedback:create - - question:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: true - estimating: - activityType: estimating - enabled: true - handler: estimate - prompt: - system: | - You are the Tester for this TreeSeed project. Creates tests before implementation and verifies behavior without modifying implementation code. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: estimating - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - estimate:create - - dependency_declaration:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - reviewing: - activityType: reviewing - enabled: true - handler: writer - prompt: - system: | - You are the Tester for this TreeSeed project. Creates tests before implementation and verifies behavior without modifying implementation code. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: reviewing - branchPolicy: - kind: read-only - base: main - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: false - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - outputs: - messageTypes: [] - modelMutations: - - review_note:create - - risk_note:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: false - acting: - activityType: acting - enabled: true - handler: actor - prompt: - system: | - You are the Tester for this TreeSeed project. Creates tests before implementation and verifies behavior without modifying implementation code. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting - branchPolicy: - kind: assignment-feature - base: staging - target: staging - branchNameTemplate: agent/{agentSlug}/{assignmentId} - worktree: new - updateBaseBeforeRun: true - mergeTargetBeforeSave: true - prefix: tester - contentAccess: - read: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - describe - - query - - read - write: - models: - - question - - objective - - note - - proposal - - decision - - knowledge - - agent - actions: - - create - - update - - link - - validate - - commit - commit: - allowed: true - tools: - allowed: - - treeseed.content.describe - - treeseed.content.query - - treeseed.content.read - - treedx.build_context - - treedx.read_repository_files - - treedx.search_workspace - - treedx.read_workspace_file - - treeseed.status - - treeseed.content.create - - treeseed.content.update - - treeseed.content.link - - treeseed.content.validate - - treeseed.content.commit - - treedx.write_workspace_file - - treedx.commit_workspace - - treeseed.changed_paths - - treeseed.verify - - treeseed.dev_plan - outputs: - messageTypes: [] - modelMutations: - - test-suite:create - - test_report:create - questionPolicy: - blockExecutionWhenCreated: true - defaultAnswerPolicy: - kind: human-or-agent - execution: - providerPreference: - - codex - maxRuntimeSeconds: 1800 - maxRetries: 2 - verificationRequired: true ---- - -Tester for the admin TreeSeed project. - -Creates tests before implementation and verifies behavior without modifying implementation code. diff --git a/docs/src/content/books/.gitkeep b/docs/src/content/books/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/books/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/decisions/.gitkeep b/docs/src/content/decisions/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/decisions/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/knowledge-packs/.gitkeep b/docs/src/content/knowledge-packs/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/knowledge-packs/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/knowledge/.gitkeep b/docs/src/content/knowledge/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/knowledge/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/notes/.gitkeep b/docs/src/content/notes/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/notes/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/objectives/core.md b/docs/src/content/objectives/core.md deleted file mode 100644 index 59b803a7..00000000 --- a/docs/src/content/objectives/core.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -id: objective:admin-core -title: TreeSeed Admin Core Objective -description: TreeSeed Admin should provide the distributable Treeseed administration portal for teams, projects, hosts, work, knowledge, catalog browsing, operational status, secret-manager workflows, and capacity operator surfaces. -date: 2026-06-22 -summary: TreeSeed Admin exists to provide the distributable Treeseed administration portal for teams, projects, hosts, work, knowledge, catalog browsing, operational status, secret-manager workflows, and capacity operator surfaces while preserving its package boundary. -status: live -timeHorizon: long-term -motivation: Package-local workdays need a stable north star from the README so humans and agents can plan, execute, review, and report work without drifting across package ownership boundaries. -primaryContributor: admin-steward -relatedQuestions: [] -relatedBooks: [] ---- - -TreeSeed Admin exists to provide the distributable Treeseed administration portal for teams, projects, hosts, work, knowledge, catalog browsing, operational status, secret-manager workflows, and capacity operator surfaces. - -This core objective is the starting direction for the TreeSeed Admin Knowledge Hub. It should influence every package-local workday, research note, implementation proposal, generated artifact, approval request, and release-readiness summary. - -Admin must stay a browser administration layer over API, SDK, Core, and UI contracts. It must not own scheduling, assignment selection, provider runtime internals, backend persistence, reusable UI primitives, or ecommerce checkout policy. - -Agents working in this project should keep outputs grounded in the package README, package-local source evidence, and the TreeSeed package ownership map. When a task would cross into another package's authority, the agent should describe the boundary and route the work to the correct project instead of mutating outside this hub. diff --git a/docs/src/content/pages/.gitkeep b/docs/src/content/pages/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/pages/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/people/.gitkeep b/docs/src/content/people/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/people/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/proposals/.gitkeep b/docs/src/content/proposals/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/proposals/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/questions/.gitkeep b/docs/src/content/questions/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/questions/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/templates/.gitkeep b/docs/src/content/templates/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/templates/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content/workdays/.gitkeep b/docs/src/content/workdays/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/docs/src/content/workdays/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/manifest.yaml b/docs/src/manifest.yaml index 07199e62..19fb3932 100644 --- a/docs/src/manifest.yaml +++ b/docs/src/manifest.yaml @@ -12,7 +12,6 @@ content: agents: ./src/content/agents books: ./src/content/books templates: ./src/content/templates - knowledge_packs: ./src/content/knowledge-packs workdays: ./src/content/workdays features: docs: true @@ -26,8 +25,6 @@ features: forms: false site: models: - knowledge_packs: - rendered: false workdays: rendered: false providers: diff --git a/docs/treeseed.site.yaml b/docs/treeseed.site.yaml index b8cfd61a..497b840a 100644 --- a/docs/treeseed.site.yaml +++ b/docs/treeseed.site.yaml @@ -1,6 +1,6 @@ name: TreeSeed Admin Knowledge Hub slug: treeseed-admin-docs -siteUrl: https://admin.treeseed.ai +siteUrl: https://admin.docs.treeseed.dev contactEmail: hello@treeseed.email hosting: kind: self_hosted_project @@ -24,15 +24,15 @@ surfaces: enabled: true provider: cloudflare rootDir: . - publicBaseUrl: https://admin.treeseed.ai + publicBaseUrl: https://admin.docs.treeseed.dev localBaseUrl: http://127.0.0.1:4321 local: runtime: local environments: staging: - domain: admin-docs-staging.treeseed.ai + domain: admin.docs.preview.treeseed.dev prod: - domain: admin.treeseed.ai + domain: admin.docs.treeseed.dev providers: agents: execution: codex diff --git a/guarantees/admin/feedback-management.ui-feature.yaml b/guarantees/admin/feedback-management.ui-feature.yaml new file mode 100644 index 00000000..b62ada51 --- /dev/null +++ b/guarantees/admin/feedback-management.ui-feature.yaml @@ -0,0 +1,38 @@ +schemaVersion: treeseed.ui-feature/v1 +id: admin.feedback-management +ownerPackage: "@treeseed/admin" +routes: [/app/feedback, "/app/feedback/[feedbackId]"] +devices: [desktop_chromium, tablet_chromium, mobile_chromium] +states: [loading, empty, unavailable, forbidden, validation, conflict, success, resolved, reopened] +capabilities: + - id: feedback.submission + routes: [/app/*] + actions: [open-panel, preserve-full-page-view-on-desktop, preserve-underlying-overlay, attach-verified-context, validate-message, submit-inline] + states: [validation, success, unavailable] + actors: { allowed: [authenticated_user], forbidden: [anonymous_user, service_principal] } + guaranteeIds: [guarantee.admin.feedback.authenticated-submission.028] + - id: feedback.screenshot-privacy + routes: [/app/*] + actions: [capture-full-page, preserve-active-overlays, stop-at-feedback-boundary, mask-sensitive-values, preserve-nonsensitive-navigation, preview, expand-preview, close-expanded-preview, replace, remove, submit-private-attachment] + states: [success, validation, unavailable] + actors: { allowed: [authenticated_user], forbidden: [anonymous_user] } + guaranteeIds: [guarantee.admin.feedback.screenshot-privacy.029] + - id: feedback.administration + routes: [/app/feedback, "/app/feedback/[feedbackId]"] + actions: [search, filter, view, triage, start-progress, resolve-with-note, reopen-with-note] + states: [loading, empty, unavailable, forbidden, conflict, success, resolved, reopened] + actors: { allowed: [platform_admin], forbidden: [market_admin, team_owner, anonymous_user] } + guaranteeIds: [guarantee.admin.feedback.manage-feedback.030] + - id: feedback.export + routes: [/app/feedback] + actions: [export-bounded-filter, observe-operation, download-private-bundle] + states: [loading, success, unavailable, forbidden] + actors: { allowed: [platform_admin], forbidden: [market_admin, team_owner, anonymous_user] } + guaranteeIds: [guarantee.admin.feedback.privacy-safe-export.031] +requiredGuarantees: + - guarantee.admin.feedback.authenticated-submission.028 + - guarantee.admin.feedback.screenshot-privacy.029 + - guarantee.admin.feedback.manage-feedback.030 + - guarantee.admin.feedback.privacy-safe-export.031 + - guarantee.admin.feedback.production-readiness.032 +requirements: { accessibility: true, console: true, network: true, visual: true, durableState: true, cleanup: true } diff --git a/guarantees/admin/feedback/authenticated-submission.guarantee.yaml b/guarantees/admin/feedback/authenticated-submission.guarantee.yaml new file mode 100644 index 00000000..19834b76 --- /dev/null +++ b/guarantees/admin/feedback/authenticated-submission.guarantee.yaml @@ -0,0 +1,30 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.admin.feedback.authenticated-submission.028 +type: admin +subtype: feedback +journey: Authenticated Feedback Submission +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: An authenticated user can report feedback inline with immutable server-verified context while the complete desktop page and other open state remain visible. +status: active +dependencies: { journeys: [], guarantees: [guarantee.user.auth.user-login.004] } +actors: { allowed: [authenticated_user], forbidden: [anonymous_user, service_principal] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, security, release] +preconditions: { fixtures: [integrated_treeseed_project], notes: [The authenticated session and active-team state exist.] } +scene: + required: true + manifest: ./scenes/submit-feedback.scene.yaml + executionKey: admin.feedback.submit + mode: { acceptance: true, demo: true, training: true } + entryRoute: /app/ + componentContract: admin.feedback-management + expectedEvidence: [playwright_trace, screenshot_on_failure, console_log, network_log] +api: { required: true, verifierRefs: [api.feedback.management] } +content: { required: false, verifierRefs: [] } +audit: { required: true, verifierRefs: [api.feedback.management] } +negativeCases: + - { id: anonymous-denied, actor: anonymous_user, verifierRefs: [api.feedback.management] } +evidence: { required: [execution_graph, playwright_trace, api_verification_log] } +notes: [This release-required guarantee intentionally has no CSV journey index.] +run: { timeoutSeconds: 600, requiredForRelease: true } diff --git a/guarantees/admin/feedback/manage-feedback.guarantee.yaml b/guarantees/admin/feedback/manage-feedback.guarantee.yaml new file mode 100644 index 00000000..f1a446b9 --- /dev/null +++ b/guarantees/admin/feedback/manage-feedback.guarantee.yaml @@ -0,0 +1,22 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.admin.feedback.manage-feedback.030 +type: admin +subtype: feedback +journey: Platform Administrator Feedback Management +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: A platform administrator can find the exact submitted feedback, inspect its private context, and triage, resolve, and reopen it with durable notes. +status: active +dependencies: { journeys: [], guarantees: [guarantee.admin.feedback.screenshot-privacy.029] } +actors: { allowed: [platform_admin], forbidden: [market_admin, team_owner, anonymous_user] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, security, release] +preconditions: { fixtures: [platform_admin], notes: [Run-correlated feedback IDs were produced through the UI.] } +scene: { required: true, manifest: ./scenes/manage-feedback.scene.yaml, executionKey: admin.feedback.manage, mode: { acceptance: true, demo: true, training: true }, entryRoute: /app/feedback, componentContract: admin.feedback-management, expectedEvidence: [playwright_trace, screenshot_on_failure, console_log, network_log] } +api: { required: true, verifierRefs: [api.feedback.management, api.feedback.run-correlated] } +content: { required: false, verifierRefs: [] } +audit: { required: true, verifierRefs: [api.feedback.run-correlated] } +negativeCases: [{ id: non-platform-admin-denied, actor: market_admin, verifierRefs: [api.feedback.management] }] +evidence: { required: [execution_graph, playwright_trace, api_verification_log] } +notes: [This release-required guarantee intentionally has no CSV journey index.] +run: { timeoutSeconds: 900, requiredForRelease: true } diff --git a/guarantees/admin/feedback/privacy-safe-export.guarantee.yaml b/guarantees/admin/feedback/privacy-safe-export.guarantee.yaml new file mode 100644 index 00000000..65542a36 --- /dev/null +++ b/guarantees/admin/feedback/privacy-safe-export.guarantee.yaml @@ -0,0 +1,22 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.admin.feedback.privacy-safe-export.031 +type: admin +subtype: feedback +journey: Privacy-safe Feedback Export +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: A platform administrator can generate and download a bounded expiring AI-safe bundle without direct personal identifiers. +status: active +dependencies: { journeys: [], guarantees: [guarantee.admin.feedback.manage-feedback.030] } +actors: { allowed: [platform_admin], forbidden: [market_admin, team_owner, anonymous_user] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, security, release] +preconditions: { fixtures: [platform_admin], notes: [Run-correlated feedback is available for export.] } +scene: { required: true, manifest: ./scenes/manage-feedback.scene.yaml, executionKey: admin.feedback.manage, mode: { acceptance: true, demo: true, training: true }, entryRoute: /app/feedback, componentContract: admin.feedback-management, expectedEvidence: [playwright_trace, network_log] } +api: { required: true, verifierRefs: [api.feedback.management] } +content: { required: false, verifierRefs: [] } +audit: { required: true, verifierRefs: [api.feedback.management] } +negativeCases: [{ id: export-forbidden, actor: team_owner, verifierRefs: [api.feedback.management] }] +evidence: { required: [execution_graph, playwright_trace, api_verification_log] } +notes: [This guarantee shares the administrator lifecycle execution and does not duplicate triage mutations.] +run: { timeoutSeconds: 900, requiredForRelease: true } diff --git a/guarantees/admin/feedback/production-readiness.guarantee.yaml b/guarantees/admin/feedback/production-readiness.guarantee.yaml new file mode 100644 index 00000000..2ec1c328 --- /dev/null +++ b/guarantees/admin/feedback/production-readiness.guarantee.yaml @@ -0,0 +1,23 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.admin.feedback.production-readiness.032 +type: admin +subtype: feedback +journey: Feedback Production Readiness +ownerPackage: "@treeseed/admin" +surface: scene +summary: Require complete responsive UI, durable persistence, private attachments, authorization, status history, privacy-safe export, audit, and cleanup coverage. +status: active +dependencies: + journeys: [] + guarantees: [guarantee.admin.feedback.authenticated-submission.028, guarantee.admin.feedback.screenshot-privacy.029, guarantee.admin.feedback.manage-feedback.030, guarantee.admin.feedback.privacy-safe-export.031] +actors: { allowed: [release_operator], forbidden: [] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, security, release] +preconditions: { fixtures: [integrated_treeseed_project], notes: [The feedback feature contract and current source closure are available.] } +api: { required: true, verifierRefs: [sdk.feedback.contracts, api.feedback.management, api.feedback.run-correlated, api.feedback.run-cleanup, ui.feedback.system, admin.feedback.ui-contracts] } +content: { required: true, verifierRefs: [admin.feedback.ui-contracts] } +audit: { required: true, verifierRefs: [api.feedback.management] } +negativeCases: [{ id: privacy-and-authorization-fail-closed, actor: anonymous_user, verifierRefs: [api.feedback.management] }] +evidence: { required: [execution_graph, api_verification_log] } +notes: [This aggregate intentionally has no scene or CSV journey index and depends on the exact product scenes.] +run: { timeoutSeconds: 900, requiredForRelease: true } diff --git a/guarantees/admin/feedback/scenes/manage-feedback.scene.yaml b/guarantees/admin/feedback/scenes/manage-feedback.scene.yaml new file mode 100644 index 00000000..195587eb --- /dev/null +++ b/guarantees/admin/feedback/scenes/manage-feedback.scene.yaml @@ -0,0 +1,134 @@ +schemaVersion: treeseed.scene/v1 +id: admin.feedback.manage +title: Administer and Export Product Feedback +description: A platform administrator finds the exact UI-created report, manages its status history, and generates a privacy-safe export. +audience: [operator, evaluator] +journey: + kind: service + proves: [feedback.administration, feedback.status-history, feedback.privacy-safe-export] + minimumSteps: 19 + requiresInteractiveAction: true + consumesState: [{ key: feedback.submitted, kind: marker }] + producesState: [{ key: feedback.exported, kind: marker, value: { status: ready } }] +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, orientation: portrait, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: { dev: { required: true, reuseExisting: true }, auth: { role: platform_admin, required: true } } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-feedback + title: Open the platform feedback collection + action: { goto: /app/feedback } + expect: { urlIncludes: /app/feedback, text: Investigate reports } + - id: search-run-feedback + title: Search for the exact run-created report + action: { fill: { role: searchbox, name: Search feedback, value: "Feedback run {{runId}} {{deviceId}}" } } + expect: { text: Submitted feedback } + - id: apply-search + title: Apply the bounded server search + action: { click: { role: button, name: Apply filters } } + expect: { visible: [{ scene: feedback.admin.collection }] } + - id: open-result + title: Inspect the exact private record + action: { click: { css: '.ts-feedback-collection a[href^="/app/feedback/"]:visible', internal: true } } + expect: { text: "Feedback run {{runId}} {{deviceId}}", visible: [{ css: '[data-feedback-detail]', internal: true }] } + - id: triage + title: Mark the report triaged + action: { select: { role: combobox, name: Status, value: triaged } } + expect: { text: Triage and resolve } + - id: save-triage + title: Persist triage inline + action: { click: { role: button, name: Update status } } + expect: { text: Feedback status updated. } + - id: dismiss-triage-toast + title: Dismiss the completed triage notification + action: { click: { css: '[data-ts-toast-id]:last-of-type .ts-toast__dismiss', internal: true } } + expect: { text: Status history } + - id: choose-progress + title: Move the report into progress + action: { select: { role: combobox, name: Status, value: in_progress } } + expect: { text: Status history } + - id: save-progress + title: Persist progress inline + action: { click: { role: button, name: Update status } } + expect: { text: Feedback status updated. } + - id: dismiss-progress-toast + title: Dismiss the completed progress notification + action: { click: { css: '[data-ts-toast-id]:last-of-type .ts-toast__dismiss', internal: true } } + expect: { text: Status history } + - id: choose-resolution + title: Choose resolved status + action: { select: { role: combobox, name: Status, value: resolved } } + expect: { text: Administrator note } + - id: enter-resolution-note + title: Explain the resolution + action: { fill: { role: textbox, name: Administrator note, value: "Resolved during guarantee {{runId}} on {{deviceId}}." } } + expect: { text: Triage and resolve } + - id: resolve + title: Resolve with a durable note + action: { click: { role: button, name: Update status } } + expect: { text: Feedback status updated. } + - id: dismiss-resolution-toast + title: Dismiss the completed resolution notification + action: { click: { css: '[data-ts-toast-id]:last-of-type .ts-toast__dismiss', internal: true } } + expect: { text: Reopen feedback } + - id: choose-reopen + title: Reopen the resolved report + action: { select: { role: combobox, name: Status, value: in_progress } } + expect: { text: Reopen feedback } + - id: enter-reopen-note + title: Explain why work is continuing + action: { fill: { role: textbox, name: Administrator note, value: "Reopened during guarantee {{runId}} on {{deviceId}}." } } + expect: { text: Resolution and reopening require } + - id: reopen + title: Persist the reopening and its audit trail + action: { click: { role: button, name: Update status } } + expect: { text: Feedback status updated. } + - id: dismiss-reopen-toast + title: Dismiss the completed reopening notification + action: { click: { css: '[data-ts-toast-id]:last-of-type .ts-toast__dismiss', internal: true } } + expect: { text: Triage and resolve } + - id: choose-final-resolution + title: Resolve the reopened report + action: { select: { role: combobox, name: Status, value: resolved } } + expect: { text: Administrator note } + - id: enter-final-resolution-note + title: Record the final resolution + action: { fill: { role: textbox, name: Administrator note, value: "Final resolution during guarantee {{runId}} on {{deviceId}}." } } + expect: { text: Triage and resolve } + - id: resolve-again + title: Persist the final resolution + action: { click: { role: button, name: Update status } } + expect: { text: Feedback status updated. } + - id: dismiss-final-resolution-toast + title: Dismiss the final resolution notification + action: { click: { css: '[data-ts-toast-id]:last-of-type .ts-toast__dismiss', internal: true } } + expect: { text: Reopen feedback } + - id: return-collection + title: Return to the collection + action: { click: { role: link, name: Back to feedback } } + expect: { urlIncludes: /app/feedback } + - id: search-for-export + title: Bound the export to the exact run report + action: { fill: { role: searchbox, name: Search feedback, value: "Feedback run {{runId}} {{deviceId}}" } } + expect: { text: Export current results } + - id: apply-export-search + title: Apply the export filter + action: { click: { role: button, name: Apply filters } } + expect: { visible: [{ scene: feedback.admin.collection }] } + - id: export + title: Generate the privacy-safe bundle through the operations runner + action: { click: { role: button, name: Export current results } } + expect: { text: Privacy-safe feedback export is ready., visible: [{ role: link, name: Download export }] } +chapters: [] +overlays: [] +diagrams: [] +render: { remotion: { composition: treeseed-training-default, output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } }, capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } } } +runtime: { mode: training, timeouts: { sceneSeconds: 900, chapterSeconds: 120, stepSeconds: 120 }, checkpoints: { enabled: true, defaultResumable: true, everyStep: true }, progress: { heartbeatSeconds: 15 }, failure: { continueOnFailure: false } } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/admin/feedback/scenes/submit-feedback.scene.yaml b/guarantees/admin/feedback/scenes/submit-feedback.scene.yaml new file mode 100644 index 00000000..40871695 --- /dev/null +++ b/guarantees/admin/feedback/scenes/submit-feedback.scene.yaml @@ -0,0 +1,103 @@ +schemaVersion: treeseed.scene/v1 +id: admin.feedback.submit +title: Submit Product Feedback +description: Submit feedback with and without a browser-redacted screenshot while contextual help remains open. +audience: [operator, evaluator] +journey: + kind: service + proves: [feedback.submission, feedback.screenshot-privacy, feedback.overlay-coexistence] + minimumSteps: 18 + requiresInteractiveAction: true + consumesState: [{ key: auth.primary-session, kind: browser-storage }] + producesState: + - { key: feedback.submitted, kind: marker, value: { message: "Feedback run {{runId}} {{deviceId}}" } } +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, orientation: portrait, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: { dev: { required: true, reuseExisting: true } } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-account-password + title: Open an authenticated page with a sensitive form + action: { goto: "/app/account?tab=password" } + expect: { urlIncludes: /app/account, text: Change password } + - id: plant-private-canary + title: Enter a private canary that screenshot capture must mask + action: { fill: { css: 'input[name="password"]', internal: true, value: "feedback-secret-{{runId}}-{{deviceId}}" } } + expect: { text: Change password } + - id: open-help + title: Keep contextual help open beneath feedback + action: { click: { css: '.ts-help-trigger[data-ts-help-open="shell-help"][data-ts-help-knowledge-page-id="account.security"]', internal: true } } + expect: { text: TreeSeed Help } + - id: open-feedback-over-help + title: Open the non-modal feedback panel without closing help + action: { click: { css: '[data-ts-help-dialog][open] [data-ts-feedback-open]', internal: true } } + expect: { text: Tell us what could be better, visible: [{ scene: feedback.panel }] } + - id: choose-bug + title: Classify the report + action: { select: { role: combobox, name: Feedback type, value: bug } } + expect: { text: Context attached } + - id: reject-empty-details + title: Reject a report without the required details + action: { click: { css: '[data-scene="feedback.panel"] button[type="submit"]', internal: true } } + expect: { text: Please correct the highlighted fields. } + - id: prove-adjacent-validation + title: Prove the required error is displayed beside the details field + action: { click: { role: textbox, name: Details } } + expect: { text: This field is required. } + - id: enter-feedback + title: Describe the text-only run-correlated issue + action: { fill: { role: textbox, name: Details, value: "Feedback text run {{runId}} {{deviceId}}" } } + expect: { text: Context attached } + - id: submit-without-screenshot + title: Submit text-only feedback through the shared enhanced form + action: { click: { css: '[data-scene="feedback.panel"] button[type="submit"]', internal: true } } + expect: { urlIncludes: /app/account, text: Feedback sent. Reference } + - id: prove-help-remained-open + title: Verify the underlying help state survived feedback submission + action: { click: { css: '[data-ts-help-dialog][open] [data-ts-feedback-open]', internal: true } } + expect: { text: TreeSeed Help, visible: [{ scene: feedback.panel }] } + - id: enter-screenshot-feedback + title: Describe the run-correlated screenshot report + action: { fill: { role: textbox, name: Details, value: "Feedback run {{runId}} {{deviceId}}" } } + expect: { text: Context attached } + - id: capture-preview + title: Capture the complete page and still-open help dialog without the feedback panel + action: { click: { css: '[data-scene="feedback.panel"] [data-ts-feedback-capture]', internal: true } } + expect: { text: Preview ready, visible: [{ css: '[data-ts-feedback-preview-open]:not([hidden])', internal: true }] } + - id: expand-capture-preview + title: Expand the complete full-page screenshot for review + action: { click: { role: button, name: Expand complete screenshot preview } } + expect: { text: Complete screenshot preview, visible: [{ css: '[data-ts-image-lightbox-image][src]', internal: true }] } + - id: close-expanded-preview + title: Close the expanded screenshot and return focus to the thumbnail + action: { click: { role: button, name: Close dialog } } + expect: { text: Preview ready, visible: [{ role: button, name: Expand complete screenshot preview }] } + - id: remove-preview + title: Remove the optional screenshot before submission + action: { click: { css: '[data-scene="feedback.panel"] [data-ts-feedback-remove]', internal: true } } + expect: { text: Screenshot removed. } + - id: replace-preview + title: Capture a replacement redacted preview + action: { click: { css: '[data-scene="feedback.panel"] [data-ts-feedback-capture]', internal: true } } + expect: { text: Preview ready, visible: [{ role: button, name: Replace screenshot }] } + - id: submit-with-screenshot + title: Submit through the enhanced form without page navigation + action: { click: { css: '[data-scene="feedback.panel"] button[type="submit"]', internal: true } } + expect: { urlIncludes: /app/account, text: Feedback sent. Reference, visible: [{ css: '[data-ts-toast-id][data-tone="success"]:last-of-type', internal: true }] } + - id: close-help + title: Close only contextual help and restore page focus + action: { click: { role: button, name: Close help } } + expect: { urlIncludes: /app/account } +chapters: [] +overlays: [] +diagrams: [] +render: { remotion: { composition: treeseed-training-default, output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } }, capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } } } +runtime: { mode: training, timeouts: { sceneSeconds: 600, chapterSeconds: 120, stepSeconds: 90 }, checkpoints: { enabled: true, defaultResumable: true, everyStep: true }, progress: { heartbeatSeconds: 15 }, failure: { continueOnFailure: false } } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/admin/feedback/screenshot-privacy.guarantee.yaml b/guarantees/admin/feedback/screenshot-privacy.guarantee.yaml new file mode 100644 index 00000000..d07b29cc --- /dev/null +++ b/guarantees/admin/feedback/screenshot-privacy.guarantee.yaml @@ -0,0 +1,22 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.admin.feedback.screenshot-privacy.029 +type: admin +subtype: feedback +journey: Feedback Screenshot Privacy +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Optional screenshots preserve the complete page and active overlays without the feedback panel, redact private values in the browser, and remain privately stored. +status: active +dependencies: { journeys: [], guarantees: [guarantee.admin.feedback.authenticated-submission.028] } +actors: { allowed: [authenticated_user], forbidden: [anonymous_user] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, security, release] +preconditions: { fixtures: [integrated_treeseed_project], notes: [The feedback submission session is active.] } +scene: { required: true, manifest: ./scenes/submit-feedback.scene.yaml, executionKey: admin.feedback.submit, mode: { acceptance: true, demo: true, training: true }, entryRoute: /app/, componentContract: admin.feedback-management, expectedEvidence: [playwright_trace, screenshot_on_failure, network_log] } +api: { required: true, verifierRefs: [api.feedback.management] } +content: { required: false, verifierRefs: [] } +audit: { required: true, verifierRefs: [api.feedback.management] } +negativeCases: [{ id: attachment-private, actor: non_admin_user, verifierRefs: [api.feedback.management] }] +evidence: { required: [execution_graph, playwright_trace, api_verification_log] } +notes: [This guarantee shares one real submission execution instead of duplicating its UI mutations.] +run: { timeoutSeconds: 600, requiredForRelease: true } diff --git a/guarantees/admin/knowledge-authoring.ui-feature.yaml b/guarantees/admin/knowledge-authoring.ui-feature.yaml new file mode 100644 index 00000000..63c2c187 --- /dev/null +++ b/guarantees/admin/knowledge-authoring.ui-feature.yaml @@ -0,0 +1,81 @@ +schemaVersion: treeseed.ui-feature/v1 +id: admin.knowledge-authoring +ownerPackage: "@treeseed/admin" +routes: + - /books + - "/t/[teamSlug]/books/[bookSlug]" + - "/t/[teamSlug]/books/[bookSlug]/[...pageSlug]" + - /app/knowledge + - "/app/projects/[projectId]/books" +devices: [desktop_chromium, tablet_chromium, mobile_chromium] +states: [loading, empty, unavailable, forbidden, validation, conflict, success, archived, review, published] +capabilities: + - id: knowledge.library + routes: [/books, /app/knowledge, "/app/projects/[projectId]/books"] + actions: [search, filter, inspect-book, inspect-outline, open-reader] + states: [loading, empty, unavailable, forbidden, success] + actors: { allowed: [anonymous_user, authenticated_user, team_member], forbidden: [unauthorized_private_viewer] } + guaranteeIds: [guarantee.project.book.search-books.068] + - id: knowledge.book-authoring + routes: [/app/knowledge, "/app/projects/[projectId]/books"] + actions: [create-workspace, edit-metadata, validate, checkpoint, submit-review, abandon-workspace] + states: [validation, conflict, success, review, unavailable, forbidden] + actors: { allowed: [knowledge_author, project_contributor, project_manager], forbidden: [anonymous_user, non_member, project_viewer] } + guaranteeIds: [guarantee.project.book.create-book.065, guarantee.project.book.edit-book.066] + - id: knowledge.book-lifecycle + routes: [/app/knowledge] + actions: [inspect-dependencies, archive, restore] + states: [validation, conflict, archived, success, forbidden] + actors: { allowed: [project_manager], forbidden: [project_contributor, project_viewer, non_member, anonymous_user] } + guaranteeIds: [guarantee.project.book.delete-book.067] + - id: knowledge.page-authoring + routes: [/app/knowledge] + actions: [edit-markdown, edit-metadata, preview, inspect-diff, checkpoint, submit-review] + states: [validation, conflict, success, review, unavailable, forbidden] + actors: { allowed: [knowledge_author, project_contributor, project_manager], forbidden: [anonymous_user, non_member, project_viewer] } + guaranteeIds: [guarantee.project.knowledge.create-book-page.069, guarantee.project.knowledge.edit-book-page.071] + - id: knowledge.relationships + routes: [/app/knowledge] + actions: [search-related-content, link-content, unlink-content, inspect-backlinks] + states: [empty, validation, success, unavailable, forbidden] + actors: { allowed: [knowledge_author, project_contributor, project_manager], forbidden: [anonymous_user, non_member, project_viewer] } + guaranteeIds: [guarantee.project.knowledge.create-book-page.069, guarantee.project.knowledge.review-backlinks.091] + - id: knowledge.page-lifecycle + routes: [/app/knowledge] + actions: [inspect-backlinks, inspect-pack-dependencies, archive, restore] + states: [validation, conflict, archived, success, forbidden] + actors: { allowed: [project_manager], forbidden: [project_contributor, project_viewer, non_member, anonymous_user] } + guaranteeIds: [guarantee.project.knowledge.delete-book-page.072] + - id: knowledge.review-publication + routes: [/app/knowledge] + actions: [inspect-diff, review-rendering, approve, reject, publish, observe-operation] + states: [review, validation, conflict, published, unavailable, forbidden] + actors: { allowed: [knowledge_reviewer, project_manager], forbidden: [author_without_review_permission, non_member, anonymous_user] } + guaranteeIds: [guarantee.project.book.create-book.065, guarantee.project.knowledge.create-book-page.069, guarantee.project.library.rebuild-library-index.090] + - id: knowledge.packs + routes: [/app/knowledge] + actions: [save-collection, select-books, preview-closure, build-pack, observe-operation, download-pack] + states: [empty, validation, success, unavailable, forbidden] + actors: { allowed: [knowledge_pack_builder, project_contributor, project_manager], forbidden: [anonymous_user, non_member, unauthorized_private_viewer] } + guaranteeIds: [guarantee.project.book.download-book.070, guarantee.project.library.download-library.073] + - id: knowledge.reader + routes: ["/t/[teamSlug]/books/[bookSlug]", "/t/[teamSlug]/books/[bookSlug]/[...pageSlug]"] + actions: [browse-outline, follow-heading, navigate-previous-next, inspect-related-pages, inspect-backlinks, open-authoring] + states: [loading, empty, unavailable, forbidden, success] + actors: { allowed: [anonymous_user, authenticated_user, authorized_private_viewer], forbidden: [unauthorized_private_viewer] } + guaranteeIds: [guarantee.project.book.search-books.068, guarantee.project.knowledge.review-backlinks.091] +requiredGuarantees: + - guarantee.project.book.create-book.065 + - guarantee.project.book.edit-book.066 + - guarantee.project.book.delete-book.067 + - guarantee.project.book.search-books.068 + - guarantee.project.knowledge.create-book-page.069 + - guarantee.project.book.download-book.070 + - guarantee.project.knowledge.edit-book-page.071 + - guarantee.project.knowledge.delete-book-page.072 + - guarantee.project.library.download-library.073 + - guarantee.project.library.rebuild-library-index.090 + - guarantee.project.knowledge.review-backlinks.091 + - guarantee.admin.knowledge.knowledge-authoring.565 + - guarantee.admin.knowledge.contextual-knowledge.566 +requirements: { accessibility: true, console: true, network: true, visual: true, durableState: true, cleanup: true } diff --git a/guarantees/admin/knowledge/contextual-knowledge.guarantee.yaml b/guarantees/admin/knowledge/contextual-knowledge.guarantee.yaml new file mode 100644 index 00000000..a6f60073 --- /dev/null +++ b/guarantees/admin/knowledge/contextual-knowledge.guarantee.yaml @@ -0,0 +1,26 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.admin.knowledge.contextual-knowledge.566 +type: admin +subtype: knowledge +journey: Contextual Knowledge Production Readiness +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Require contextual help to resolve authorized published book pages and TreeDX graph relationships without metadata leakage. +status: active +dependencies: + journeys: [68, 69, 91] + guarantees: [] +actors: { allowed: [authenticated_user, team_member, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, security, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.library, knowledge.relationships, knowledge.reader] } +scene: { required: true, manifest: ../../project/book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: contextual knowledge dialog and canonical reader } +api: { required: true, verifierRefs: [api.knowledge.contextual-policy] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content, core.knowledge.starlight-reader, admin.knowledge.ui-contracts] } +audit: { required: false, verifierRefs: [] } +negativeCases: + - { id: unauthorized-context-is-hidden, actor: unauthorized_user, sceneManifest: ../../project/book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.contextual-policy] } +evidence: { required: [execution_graph, playwright_trace, api_verification_log, treedx_content_ref] } +notes: [No-index release aggregate; the exact published page is resolved in the shared dialog while policy tests prove inaccessible knowledge and edges remain hidden.] +run: { requiredForRelease: true } diff --git a/guarantees/admin/knowledge/knowledge-authoring.guarantee.yaml b/guarantees/admin/knowledge/knowledge-authoring.guarantee.yaml new file mode 100644 index 00000000..f9a95b0a --- /dev/null +++ b/guarantees/admin/knowledge/knowledge-authoring.guarantee.yaml @@ -0,0 +1,28 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.admin.knowledge.knowledge-authoring.565 +type: admin +subtype: knowledge +journey: Knowledge Authoring Production Readiness +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Require complete book and page authoring, linking, review, publication, lifecycle, and pack workflows through rendered controls. +status: active +dependencies: + journeys: [65, 66, 67, 68, 69, 70, 71, 72, 73, 90, 91] + guarantees: [] +actors: { allowed: [knowledge_author, knowledge_reviewer, project_manager, team_owner], forbidden: [anonymous_user, non_member] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, security, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.library, knowledge.book-authoring, knowledge.book-lifecycle, knowledge.page-authoring, knowledge.relationships, knowledge.page-lifecycle, knowledge.review-publication, knowledge.packs, knowledge.reader] } +scene: { required: true, manifest: ../../project/book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: complete knowledge workbench } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.run-correlated, api.knowledge.pack.run-correlated, api.knowledge.collection.run-correlated, api.knowledge.lifecycle.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content, sdk.knowledge.content-sync, sdk.knowledge.pack-integrity, core.knowledge.starlight-reader, admin.knowledge.ui-contracts] } +audit: { required: true, verifierRefs: [api.knowledge.run-correlated, api.knowledge.lifecycle.run-correlated, api.knowledge.pack.run-correlated, api.knowledge.collection.run-correlated] } +negativeCases: + - { id: anonymous-knowledge-administration-denied, actor: anonymous_user, sceneManifest: ../../project/book/scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-knowledge-administration-denied, actor: non_member, sceneManifest: ../../project/book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [execution_graph, playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } +notes: + - No-index release aggregate; it depends on journeys 65 through 73 and 90 through 91 sharing one exact per-device execution. +run: { requiredForRelease: true } diff --git a/guarantees/agent/discussion/use-non-overlapping-discussion-dock.guarantee.yaml b/guarantees/agent/discussion/use-non-overlapping-discussion-dock.guarantee.yaml new file mode 100644 index 00000000..3a0d1894 --- /dev/null +++ b/guarantees/agent/discussion/use-non-overlapping-discussion-dock.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.agent.discussion.use-non-overlapping-discussion-dock.749 +journeyIndex: 749 +type: agent +subtype: discussion +journey: Use the non-overlapping Discussion dock +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Search and continue TreeDX Discussions, edit Markdown, reference files, and observe assignment resource traces without covering page content. +status: planned +dependencies: { journeys: [744], guarantees: [guarantee.agent.discussion.persist-discussion-only-in-treedx.744] } +actors: { allowed: [authenticated_user, team_owner], forbidden: [anonymous_user] } +devices: { required: [desktop_chromium], optional: [mobile_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: true, verifierRefs: [] } +content: { required: true, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [{ id: field-addressable-content-error, actor: authenticated_user, verifierRefs: [] }] +evidence: { required: [guarantee_report, scene_screenshots] } +notes: ["The shared UI dock now marks an optimistic message failed and renders field-addressable API/TreeDX diagnostics as a Platform message. Activate after the stable Agent Lab Discussion scene produces repeatable evidence for this state and the rest of the dock journey."] diff --git a/guarantees/capacity/capacity/approve-capacity.guarantee.yaml b/guarantees/capacity/capacity/approve-capacity.guarantee.yaml deleted file mode 100644 index a433fa07..00000000 --- a/guarantees/capacity/capacity/approve-capacity.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.capacity.capacity.approve-capacity.027 -journeyIndex: 27 -type: capacity -subtype: capacity -journey: Approve Capacity -ownerPackage: "@treeseed/admin" -summary: Approve provider availability or registration for team/project use; API owns durable availability sessions and policy decisions. -status: active -dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 -actors: - allowed: - - capacity_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 4" -scene: - required: true - manifest: ./scenes/approve-capacity.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity - componentContract: record-action service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.capacity.capacity.approve-capacity.api -content: - required: false - verifierRefs: - - admin.capacity.capacity.approve-capacity.content -audit: - required: true - verifierRefs: - - admin.capacity.capacity.approve-capacity.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.capacity.capacity.approve-capacity.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Approve provider availability or registration for team/project use; API owns durable availability sessions and policy decisions. diff --git a/guarantees/capacity/capacity/deploy-capacity.guarantee.yaml b/guarantees/capacity/capacity/deploy-capacity.guarantee.yaml deleted file mode 100644 index f94b6f37..00000000 --- a/guarantees/capacity/capacity/deploy-capacity.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.capacity.capacity.deploy-capacity.028 -journeyIndex: 28 -type: capacity -subtype: capacity -journey: Deploy Capacity -ownerPackage: "@treeseed/admin" -summary: Start or reconcile provider runtime through the agent package lifecycle and trsd capacity commands; UI should trigger desired-state operations not bespoke deployment scripts. -status: active -dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 -actors: - allowed: - - capacity_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 4" -scene: - required: true - manifest: ./scenes/deploy-capacity.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/runtime - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.capacity.capacity.deploy-capacity.api -content: - required: false - verifierRefs: - - admin.capacity.capacity.deploy-capacity.content -audit: - required: true - verifierRefs: - - admin.capacity.capacity.deploy-capacity.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.capacity.capacity.deploy-capacity.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Start or reconcile provider runtime through the agent package lifecycle and trsd capacity commands; UI should trigger desired-state operations not bespoke deployment scripts. diff --git a/guarantees/capacity/capacity/monitor-capacity.guarantee.yaml b/guarantees/capacity/capacity/monitor-capacity.guarantee.yaml deleted file mode 100644 index 043e51f6..00000000 --- a/guarantees/capacity/capacity/monitor-capacity.guarantee.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.capacity.capacity.monitor-capacity.029 -journeyIndex: 29 -type: capacity -subtype: capacity -journey: Monitor Capacity -ownerPackage: "@treeseed/admin" -summary: Show provider manager runner availability leases usage and diagnostics; data should come from API control-plane records and provider check-ins. -status: active -dependencies: - journeys: - - 27 - - 28 - guarantees: - - guarantee.capacity.capacity.approve-capacity.027 - - guarantee.capacity.capacity.deploy-capacity.028 -actors: - allowed: - - capacity_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 27, 28" -scene: - required: true - manifest: ./scenes/monitor-capacity.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/runtime - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.capacity.capacity.monitor-capacity.api -content: - required: false - verifierRefs: - - admin.capacity.capacity.monitor-capacity.content -audit: - required: true - verifierRefs: - - admin.capacity.capacity.monitor-capacity.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.capacity.capacity.monitor-capacity.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Show provider manager runner availability leases usage and diagnostics; data should come from API control-plane records and provider check-ins. diff --git a/guarantees/capacity/capacity/revoke-capacity.guarantee.yaml b/guarantees/capacity/capacity/revoke-capacity.guarantee.yaml deleted file mode 100644 index 8a803fd4..00000000 --- a/guarantees/capacity/capacity/revoke-capacity.guarantee.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.capacity.capacity.revoke-capacity.031 -journeyIndex: 31 -type: capacity -subtype: capacity -journey: Revoke Capacity -ownerPackage: "@treeseed/admin" -summary: Revoke provider eligibility or keys and return active leases safely; must coordinate with API assignment and settlement records. -status: active -dependencies: - journeys: - - 27 - - 28 - guarantees: - - guarantee.capacity.capacity.approve-capacity.027 - - guarantee.capacity.capacity.deploy-capacity.028 -actors: - allowed: - - capacity_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 27, 28" -scene: - required: true - manifest: ./scenes/revoke-capacity.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/runtime - componentContract: record-action service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.capacity.capacity.revoke-capacity.api -content: - required: false - verifierRefs: - - admin.capacity.capacity.revoke-capacity.content -audit: - required: true - verifierRefs: - - admin.capacity.capacity.revoke-capacity.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.capacity.capacity.revoke-capacity.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Revoke provider eligibility or keys and return active leases safely; must coordinate with API assignment and settlement records. diff --git a/guarantees/capacity/capacity/scenes/approve-capacity.scene.yaml b/guarantees/capacity/capacity/scenes/approve-capacity.scene.yaml deleted file mode 100644 index 0d5d9339..00000000 --- a/guarantees/capacity/capacity/scenes/approve-capacity.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: capacity.capacity.approve-capacity.027 -title: Approve Capacity -description: Scene scaffold for guarantee.capacity.capacity.approve-capacity.027. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Approve Capacity opens the canonical @treeseed/admin record action workflow. - - Approve Capacity exercises a service journey instead of only loading /app/capacity. - - Approve Capacity records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Approve Capacity - action: - goto: /app/capacity - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Approve Capacity service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/capacity/capacity/scenes/deploy-capacity.scene.yaml b/guarantees/capacity/capacity/scenes/deploy-capacity.scene.yaml deleted file mode 100644 index 736cea64..00000000 --- a/guarantees/capacity/capacity/scenes/deploy-capacity.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: capacity.capacity.deploy-capacity.028 -title: Deploy Capacity -description: Scene scaffold for guarantee.capacity.capacity.deploy-capacity.028. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Deploy Capacity opens the canonical @treeseed/admin record action workflow. - - Deploy Capacity exercises a service journey instead of only loading /app/capacity/runtime. - - Deploy Capacity records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Deploy Capacity - action: - goto: /app/capacity/runtime - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Deploy Capacity service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/capacity/capacity/scenes/monitor-capacity.scene.yaml b/guarantees/capacity/capacity/scenes/monitor-capacity.scene.yaml deleted file mode 100644 index d0a4fc38..00000000 --- a/guarantees/capacity/capacity/scenes/monitor-capacity.scene.yaml +++ /dev/null @@ -1,121 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: capacity.capacity.monitor-capacity.029 -title: Monitor Capacity -description: Scene scaffold for guarantee.capacity.capacity.monitor-capacity.029. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Monitor Capacity opens the canonical @treeseed/admin record operations workflow. - - Monitor Capacity exercises a service journey instead of only loading /app/capacity/runtime. - - Monitor Capacity records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - auth: - required: true - role: owner - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Monitor Capacity - action: - goto: /app/capacity/runtime - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Monitor Capacity service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/capacity/capacity/scenes/revoke-capacity.scene.yaml b/guarantees/capacity/capacity/scenes/revoke-capacity.scene.yaml deleted file mode 100644 index 3d4b2e4a..00000000 --- a/guarantees/capacity/capacity/scenes/revoke-capacity.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: capacity.capacity.revoke-capacity.031 -title: Revoke Capacity -description: Scene scaffold for guarantee.capacity.capacity.revoke-capacity.031. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Revoke Capacity opens the canonical @treeseed/admin destructive confirmation workflow. - - Revoke Capacity exercises a service journey instead of only loading /app/capacity/runtime. - - Revoke Capacity records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Revoke Capacity - action: - goto: /app/capacity/runtime - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Revoke Capacity service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/capacity/capacity/scenes/shut-down-capacity.scene.yaml b/guarantees/capacity/capacity/scenes/shut-down-capacity.scene.yaml deleted file mode 100644 index 8aa9f796..00000000 --- a/guarantees/capacity/capacity/scenes/shut-down-capacity.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: capacity.capacity.shut-down-capacity.030 -title: Shut Down Capacity -description: Scene scaffold for guarantee.capacity.capacity.shut-down-capacity.030. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Shut Down Capacity opens the canonical @treeseed/admin record operations workflow. - - Shut Down Capacity exercises a service journey instead of only loading /app/capacity/runtime. - - Shut Down Capacity records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Shut Down Capacity - action: - goto: /app/capacity/runtime - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Shut Down Capacity service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/capacity/capacity/shut-down-capacity.guarantee.yaml b/guarantees/capacity/capacity/shut-down-capacity.guarantee.yaml deleted file mode 100644 index fd05b300..00000000 --- a/guarantees/capacity/capacity/shut-down-capacity.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.capacity.capacity.shut-down-capacity.030 -journeyIndex: 30 -type: capacity -subtype: capacity -journey: Shut Down Capacity -ownerPackage: "@treeseed/admin" -summary: Stop provider runtime through reconciliation while preserving volumes logs and state as required; should not manually kill provider resources. -status: active -dependencies: - journeys: - - 28 - guarantees: - - guarantee.capacity.capacity.deploy-capacity.028 -actors: - allowed: - - capacity_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 28" -scene: - required: true - manifest: ./scenes/shut-down-capacity.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/runtime - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.capacity.capacity.shut-down-capacity.api -content: - required: false - verifierRefs: - - admin.capacity.capacity.shut-down-capacity.content -audit: - required: true - verifierRefs: - - admin.capacity.capacity.shut-down-capacity.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.capacity.capacity.shut-down-capacity.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Stop provider runtime through reconciliation while preserving volumes logs and state as required; should not manually kill provider resources. diff --git a/guarantees/capacity/registration/rotate-capacity-key.guarantee.yaml b/guarantees/capacity/registration/rotate-capacity-key.guarantee.yaml deleted file mode 100644 index bb54713d..00000000 --- a/guarantees/capacity/registration/rotate-capacity-key.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.capacity.registration.rotate-capacity-key.026 -journeyIndex: 26 -type: capacity -subtype: registration -journey: Rotate Capacity Key -ownerPackage: "@treeseed/admin" -summary: Rotate provider API keys used by capacity providers; the API should issue and track keys without exposing raw credentials in the UI. -status: active -dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 -actors: - allowed: - - capacity_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 4" -scene: - required: true - manifest: ./scenes/rotate-capacity-key.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/providers/seed-provider/keys - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.capacity.registration.rotate-capacity-key.api -content: - required: false - verifierRefs: - - admin.capacity.registration.rotate-capacity-key.content -audit: - required: true - verifierRefs: - - admin.capacity.registration.rotate-capacity-key.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.capacity.registration.rotate-capacity-key.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Rotate provider API keys used by capacity providers; the API should issue and track keys without exposing raw credentials in the UI. diff --git a/guarantees/capacity/registration/scenes/rotate-capacity-key.scene.yaml b/guarantees/capacity/registration/scenes/rotate-capacity-key.scene.yaml deleted file mode 100644 index 2e17d3cc..00000000 --- a/guarantees/capacity/registration/scenes/rotate-capacity-key.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: capacity.registration.rotate-capacity-key.026 -title: Rotate Capacity Key -description: Scene scaffold for guarantee.capacity.registration.rotate-capacity-key.026. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Rotate Capacity Key opens the canonical @treeseed/admin record operations workflow. - - Rotate Capacity Key exercises a service journey instead of only loading /app/capacity/providers/seed-provider/keys. - - Rotate Capacity Key records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Rotate Capacity Key - action: - goto: /app/capacity/providers/seed-provider/keys - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Rotate Capacity Key service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/content/management/archive-and-restore-a-book.guarantee.yaml b/guarantees/content/management/archive-and-restore-a-book.guarantee.yaml new file mode 100644 index 00000000..05641211 --- /dev/null +++ b/guarantees/content/management/archive-and-restore-a-book.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.archive-and-restore-a-book.648 +journeyIndex: 648 +type: content +subtype: management +journey: "Archive and restore a book" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can archive and restore a book." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/create-a-hierarchical-knowledge-page.guarantee.yaml b/guarantees/content/management/create-a-hierarchical-knowledge-page.guarantee.yaml new file mode 100644 index 00000000..8e804f75 --- /dev/null +++ b/guarantees/content/management/create-a-hierarchical-knowledge-page.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.create-a-hierarchical-knowledge-page.649 +journeyIndex: 649 +type: content +subtype: management +journey: "Create a hierarchical knowledge page" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can create a hierarchical knowledge page." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/create-a-knowledge-book.guarantee.yaml b/guarantees/content/management/create-a-knowledge-book.guarantee.yaml new file mode 100644 index 00000000..2c20ac78 --- /dev/null +++ b/guarantees/content/management/create-a-knowledge-book.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.create-a-knowledge-book.646 +journeyIndex: 646 +type: content +subtype: management +journey: "Create a knowledge book" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can create a knowledge book." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/edit-book-metadata.guarantee.yaml b/guarantees/content/management/edit-book-metadata.guarantee.yaml new file mode 100644 index 00000000..fddb2b43 --- /dev/null +++ b/guarantees/content/management/edit-book-metadata.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.edit-book-metadata.647 +journeyIndex: 647 +type: content +subtype: management +journey: "Edit book metadata" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can edit book metadata." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/move-a-page-within-a-book.guarantee.yaml b/guarantees/content/management/move-a-page-within-a-book.guarantee.yaml new file mode 100644 index 00000000..8f8f7234 --- /dev/null +++ b/guarantees/content/management/move-a-page-within-a-book.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.move-a-page-within-a-book.650 +journeyIndex: 650 +type: content +subtype: management +journey: "Move a page within a book" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can move a page within a book." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/publish-an-atomic-knowledge-revision.guarantee.yaml b/guarantees/content/management/publish-an-atomic-knowledge-revision.guarantee.yaml new file mode 100644 index 00000000..a8b66084 --- /dev/null +++ b/guarantees/content/management/publish-an-atomic-knowledge-revision.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.publish-an-atomic-knowledge-revision.653 +journeyIndex: 653 +type: content +subtype: management +journey: "Publish an atomic knowledge revision" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can publish an atomic knowledge revision." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/review-knowledge-backlinks.guarantee.yaml b/guarantees/content/management/review-knowledge-backlinks.guarantee.yaml new file mode 100644 index 00000000..6070e497 --- /dev/null +++ b/guarantees/content/management/review-knowledge-backlinks.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.review-knowledge-backlinks.652 +journeyIndex: 652 +type: content +subtype: management +journey: "Review knowledge backlinks" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can review knowledge backlinks." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/validate-a-knowledge-hierarchy.guarantee.yaml b/guarantees/content/management/validate-a-knowledge-hierarchy.guarantee.yaml new file mode 100644 index 00000000..3f944556 --- /dev/null +++ b/guarantees/content/management/validate-a-knowledge-hierarchy.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.validate-a-knowledge-hierarchy.651 +journeyIndex: 651 +type: content +subtype: management +journey: "Validate a knowledge hierarchy" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can validate a knowledge hierarchy." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/content/management/validate-knowledge-page-frontmatter-contracts.guarantee.yaml b/guarantees/content/management/validate-knowledge-page-frontmatter-contracts.guarantee.yaml new file mode 100644 index 00000000..9ff9080b --- /dev/null +++ b/guarantees/content/management/validate-knowledge-page-frontmatter-contracts.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.content.management.validate-knowledge-page-frontmatter-contracts.654 +journeyIndex: 654 +type: content +subtype: management +journey: "Validate knowledge page frontmatter contracts" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can validate knowledge page frontmatter contracts." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/evidence-admissibility/2026-07-27-team-evidence.yaml b/guarantees/evidence-admissibility/2026-07-27-team-evidence.yaml new file mode 100644 index 00000000..0ff120f5 --- /dev/null +++ b/guarantees/evidence-admissibility/2026-07-27-team-evidence.yaml @@ -0,0 +1,35 @@ +schemaVersion: treeseed.guarantee-evidence-admissibility/v1 +ownerPackage: "@treeseed/admin" +recordedAt: 2026-07-27T17:00:00.000Z +scope: + guaranteeIds: + - guarantee.team.team.create-team.012 + - guarantee.team.team.switch-active-team.013 + - guarantee.team.team.edit-team-settings.014 + - guarantee.team.team.view-team-profile.015 + - guarantee.team.team.delete-team.016 + - guarantee.team.membership.invite-team-members.017 + - guarantee.team.membership.accept-team-invitation.018 + - guarantee.team.membership.change-member-role.019 + - guarantee.team.membership.remove-team-member.020 + runIds: + - 2026-07-27T00-25-09-417Z + - 2026-07-27T00-27-48-988Z + - 2026-07-27T00-34-25-348Z + - 2026-07-27T00-50-52-953Z + - 2026-07-27T01-00-37-183Z + - 2026-07-27T01-09-35-100Z +decision: inadmissible +reasons: + - Mobile graph nodes were populated from scenes whose reports recorded desktop Chromium device metadata and a 1600x900 desktop viewport. + - Per-device graph status copied aggregate guarantee status instead of using the actual result for the requested device. + - Several durable verifiers inspected fixture-created records rather than the records created by the corresponding rendered UI journey. + - Journey 15 asserted the anonymous public profile instead of the required authenticated operational overview. +history: + immutable: true + action: Preserve the original report, graph, scene, trace, screenshot, console, network, and API artifacts as historical diagnostics. + acceptanceUse: forbidden +replacementRequirements: + - Exact requested and actual device metadata must match before evidence is accepted. + - UI-created record identifiers must flow through run state to API and audit verifiers. + - Journeys 12 through 20 and the separate public-profile guarantee must pass from the current source closure. diff --git a/guarantees/host/host/create-host.guarantee.yaml b/guarantees/host/host/create-host.guarantee.yaml deleted file mode 100644 index 63d773ad..00000000 --- a/guarantees/host/host/create-host.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.host.host.create-host.023 -journeyIndex: 23 -type: host -subtype: host -journey: Create Host -ownerPackage: "@treeseed/admin" -summary: Register a hostable environment or provider target as desired state; creation should compile reconciliation resources instead of calling providers directly. -status: active -dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 -actors: - allowed: - - host_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 4" -scene: - required: true - manifest: ./scenes/create-host.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/hosts/new - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.host.host.create-host.api -content: - required: false - verifierRefs: - - admin.host.host.create-host.content -audit: - required: true - verifierRefs: - - admin.host.host.create-host.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.host.host.create-host.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Register a hostable environment or provider target as desired state; creation should compile reconciliation resources instead of calling providers directly. diff --git a/guarantees/host/host/delete-host.guarantee.yaml b/guarantees/host/host/delete-host.guarantee.yaml deleted file mode 100644 index 2d9a4f0c..00000000 --- a/guarantees/host/host/delete-host.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.host.host.delete-host.025 -journeyIndex: 25 -type: host -subtype: host -journey: Delete Host -ownerPackage: "@treeseed/admin" -summary: Plan destroy or retention for owned resources using reconciliation lifecycle; direct provider deletion would violate the architecture. -status: active -dependencies: - journeys: - - 23 - guarantees: - - guarantee.host.host.create-host.023 -actors: - allowed: - - host_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 23" -scene: - required: true - manifest: ./scenes/delete-host.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/hosts/web/seed-host - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.host.host.delete-host.api -content: - required: false - verifierRefs: - - admin.host.host.delete-host.content -audit: - required: true - verifierRefs: - - admin.host.host.delete-host.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.host.host.delete-host.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Plan destroy or retention for owned resources using reconciliation lifecycle; direct provider deletion would violate the architecture. diff --git a/guarantees/host/host/edit-host.guarantee.yaml b/guarantees/host/host/edit-host.guarantee.yaml deleted file mode 100644 index ac718aa6..00000000 --- a/guarantees/host/host/edit-host.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.host.host.edit-host.024 -journeyIndex: 24 -type: host -subtype: host -journey: Edit Host -ownerPackage: "@treeseed/admin" -summary: Edit host configuration such as domains provider bindings and environment metadata; changes must flow through trsd reconciliation plans. -status: active -dependencies: - journeys: - - 23 - guarantees: - - guarantee.host.host.create-host.023 -actors: - allowed: - - host_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 23" -scene: - required: true - manifest: ./scenes/edit-host.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/hosts - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.host.host.edit-host.api -content: - required: false - verifierRefs: - - admin.host.host.edit-host.content -audit: - required: true - verifierRefs: - - admin.host.host.edit-host.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.host.host.edit-host.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Edit host configuration such as domains provider bindings and environment metadata; changes must flow through trsd reconciliation plans. diff --git a/guarantees/host/host/scenes/create-host.scene.yaml b/guarantees/host/host/scenes/create-host.scene.yaml deleted file mode 100644 index abd5d3c5..00000000 --- a/guarantees/host/host/scenes/create-host.scene.yaml +++ /dev/null @@ -1,119 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: host.host.create-host.023 -title: Create Host -description: Scene scaffold for guarantee.host.host.create-host.023. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Host opens the canonical @treeseed/admin record operations workflow. - - Create Host exercises a service journey instead of only loading /app/hosts/new. - - Create Host records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - producesState: - - key: host.primary - kind: host - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Host - action: - goto: /app/hosts/new - expect: - urlIncludes: /app/hosts - - id: inspect-service-surface - title: Inspect Create Host service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/hosts -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/host/host/scenes/delete-host.scene.yaml b/guarantees/host/host/scenes/delete-host.scene.yaml deleted file mode 100644 index ce3b63fa..00000000 --- a/guarantees/host/host/scenes/delete-host.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: host.host.delete-host.025 -title: Delete Host -description: Scene scaffold for guarantee.host.host.delete-host.025. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Host opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Host exercises a service journey instead of only loading /app/hosts/web/seed-host. - - Delete Host records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: host.primary - kind: host -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Host - action: - goto: /app/hosts/web/seed-host - expect: - urlIncludes: /app/hosts - - id: inspect-service-surface - title: Inspect Delete Host service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/hosts -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/host/host/scenes/edit-host.scene.yaml b/guarantees/host/host/scenes/edit-host.scene.yaml deleted file mode 100644 index 040e693e..00000000 --- a/guarantees/host/host/scenes/edit-host.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: host.host.edit-host.024 -title: Edit Host -description: Scene scaffold for guarantee.host.host.edit-host.024. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Host opens the canonical @treeseed/admin record operations workflow. - - Edit Host exercises a service journey from the canonical host inventory surface. - - Edit Host records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: host.primary - kind: host -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Host - action: - goto: /app/hosts - expect: - urlIncludes: /app/hosts - - id: inspect-service-surface - title: Inspect host inventory service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/hosts -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/host/secrets/create-passphrase.guarantee.yaml b/guarantees/host/secrets/create-passphrase.guarantee.yaml deleted file mode 100644 index b103759b..00000000 --- a/guarantees/host/secrets/create-passphrase.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.host.secrets.create-passphrase.021 -journeyIndex: 21 -type: host -subtype: secrets -journey: Create Passphrase -ownerPackage: "@treeseed/admin" -summary: Create or unlock the secret-management passphrase for host/provider credentials; secrets must remain in approved secret stores and never plaintext files. -status: active -dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 -actors: - allowed: - - host_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 4" -scene: - required: true - manifest: ./scenes/create-passphrase.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/hosts/new - componentContract: modal-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.host.secrets.create-passphrase.api -content: - required: false - verifierRefs: - - admin.host.secrets.create-passphrase.content -audit: - required: true - verifierRefs: - - admin.host.secrets.create-passphrase.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.host.secrets.create-passphrase.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create or unlock the secret-management passphrase for host/provider credentials; secrets must remain in approved secret stores and never plaintext files. diff --git a/guarantees/host/secrets/reset-passphrase.guarantee.yaml b/guarantees/host/secrets/reset-passphrase.guarantee.yaml deleted file mode 100644 index 31fb658f..00000000 --- a/guarantees/host/secrets/reset-passphrase.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.host.secrets.reset-passphrase.022 -journeyIndex: 22 -type: host -subtype: secrets -journey: Reset Passphrase -ownerPackage: "@treeseed/admin" -summary: Reset secret access with recovery policy and re-encryption semantics; this is high risk because provider credentials back reconciliation. -status: active -dependencies: - journeys: - - 21 - guarantees: - - guarantee.host.secrets.create-passphrase.021 -actors: - allowed: - - host_operator - - team_owner - - platform_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 21" -scene: - required: true - manifest: ./scenes/reset-passphrase.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/hosts/web/seed-host/settings - componentContract: modal-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.host.secrets.reset-passphrase.api -content: - required: false - verifierRefs: - - admin.host.secrets.reset-passphrase.content -audit: - required: true - verifierRefs: - - admin.host.secrets.reset-passphrase.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.host.secrets.reset-passphrase.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Reset secret access with recovery policy and re-encryption semantics; this is high risk because provider credentials back reconciliation. diff --git a/guarantees/host/secrets/scenes/create-passphrase.scene.yaml b/guarantees/host/secrets/scenes/create-passphrase.scene.yaml deleted file mode 100644 index 73e809e1..00000000 --- a/guarantees/host/secrets/scenes/create-passphrase.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: host.secrets.create-passphrase.021 -title: Create Passphrase -description: Scene scaffold for guarantee.host.secrets.create-passphrase.021. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Passphrase opens the canonical @treeseed/admin record operations workflow. - - Create Passphrase exercises a service journey instead of only loading /app/hosts/new. - - Create Passphrase records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: host.primary - kind: host -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Passphrase - action: - goto: /app/hosts/new - expect: - urlIncludes: /app/hosts - - id: inspect-service-surface - title: Inspect Create Passphrase service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/hosts -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/host/secrets/scenes/reset-passphrase.scene.yaml b/guarantees/host/secrets/scenes/reset-passphrase.scene.yaml deleted file mode 100644 index 47f0cafe..00000000 --- a/guarantees/host/secrets/scenes/reset-passphrase.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: host.secrets.reset-passphrase.022 -title: Reset Passphrase -description: Scene scaffold for guarantee.host.secrets.reset-passphrase.022. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Reset Passphrase opens the canonical @treeseed/admin record operations workflow. - - Reset Passphrase exercises a service journey instead of only loading /app/hosts/web/seed-host/settings. - - Reset Passphrase records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: host.primary - kind: host -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Reset Passphrase - action: - goto: /app/hosts/web/seed-host/settings - expect: - urlIncludes: /app/hosts - - id: inspect-service-surface - title: Inspect Reset Passphrase service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/hosts -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/fulfillment/record-fulfillment.guarantee.yaml b/guarantees/marketplace-seller/fulfillment/record-fulfillment.guarantee.yaml deleted file mode 100644 index 5120d469..00000000 --- a/guarantees/marketplace-seller/fulfillment/record-fulfillment.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.fulfillment.record-fulfillment.113 -journeyIndex: 113 -type: marketplace-seller -subtype: fulfillment -journey: Record Fulfillment -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Record Fulfillment. -status: active -dependencies: - journeys: - - 112 - guarantees: - - guarantee.marketplace-seller.sales.view-seller-sales.112 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 112" -scene: - required: true - manifest: ./scenes/record-fulfillment.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams/visual-audit-team/commerce/services - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.fulfillment.record-fulfillment.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.fulfillment.record-fulfillment.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.fulfillment.record-fulfillment.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.fulfillment.record-fulfillment.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Record Fulfillment. diff --git a/guarantees/marketplace-seller/fulfillment/scenes/record-fulfillment.scene.yaml b/guarantees/marketplace-seller/fulfillment/scenes/record-fulfillment.scene.yaml deleted file mode 100644 index 13c3bcf8..00000000 --- a/guarantees/marketplace-seller/fulfillment/scenes/record-fulfillment.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.fulfillment.record-fulfillment.113 -title: Record Fulfillment -description: Scene scaffold for guarantee.marketplace-seller.fulfillment.record-fulfillment.113. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Record Fulfillment opens the canonical @treeseed/admin dashboard read model workflow. - - Record Fulfillment exercises a service journey instead of only loading /app/teams/visual-audit-team/commerce/services. - - Record Fulfillment records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Record Fulfillment - action: - goto: /app/teams/visual-audit-team/commerce/services - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Record Fulfillment service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/listings/approve-listing.guarantee.yaml b/guarantees/marketplace-seller/listings/approve-listing.guarantee.yaml deleted file mode 100644 index 72cd3ec3..00000000 --- a/guarantees/marketplace-seller/listings/approve-listing.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.listings.approve-listing.110 -journeyIndex: 110 -type: marketplace-seller -subtype: listings -journey: Approve Listing -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Approve Listing. -status: active -dependencies: - journeys: - - 109 - guarantees: - - guarantee.marketplace-seller.listings.submit-listing-for-review.109 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 109" -scene: - required: true - manifest: ./scenes/approve-listing.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams/visual-audit-team/commerce/products - componentContract: record-action service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.listings.approve-listing.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.listings.approve-listing.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.listings.approve-listing.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.listings.approve-listing.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Approve Listing. diff --git a/guarantees/marketplace-seller/listings/create-product-listing.guarantee.yaml b/guarantees/marketplace-seller/listings/create-product-listing.guarantee.yaml deleted file mode 100644 index 36e6acdb..00000000 --- a/guarantees/marketplace-seller/listings/create-product-listing.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.listings.create-product-listing.108 -journeyIndex: 108 -type: marketplace-seller -subtype: listings -journey: Create Product Listing -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Create Product Listing. -status: active -dependencies: - journeys: - - 107 - guarantees: - - guarantee.marketplace-seller.onboarding.approve-seller.107 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 107" -scene: - required: true - manifest: ./scenes/create-product-listing.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams/visual-audit-team/commerce/products - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.listings.create-product-listing.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.listings.create-product-listing.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.listings.create-product-listing.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.listings.create-product-listing.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Create Product Listing. diff --git a/guarantees/marketplace-seller/listings/manage-listing.guarantee.yaml b/guarantees/marketplace-seller/listings/manage-listing.guarantee.yaml deleted file mode 100644 index c597c252..00000000 --- a/guarantees/marketplace-seller/listings/manage-listing.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.listings.manage-listing.111 -journeyIndex: 111 -type: marketplace-seller -subtype: listings -journey: Manage Listing -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Manage Listing. -status: active -dependencies: - journeys: - - 108 - guarantees: - - guarantee.marketplace-seller.listings.create-product-listing.108 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 108" -scene: - required: true - manifest: ./scenes/manage-listing.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams/visual-audit-team/commerce/products - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.listings.manage-listing.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.listings.manage-listing.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.listings.manage-listing.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.listings.manage-listing.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Manage Listing. diff --git a/guarantees/marketplace-seller/listings/scenes/approve-listing.scene.yaml b/guarantees/marketplace-seller/listings/scenes/approve-listing.scene.yaml deleted file mode 100644 index fa3c47fd..00000000 --- a/guarantees/marketplace-seller/listings/scenes/approve-listing.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.listings.approve-listing.110 -title: Approve Listing -description: Scene scaffold for guarantee.marketplace-seller.listings.approve-listing.110. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Approve Listing opens the canonical @treeseed/admin record action workflow. - - Approve Listing exercises a service journey instead of only loading /app/teams/visual-audit-team/commerce/products. - - Approve Listing records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Approve Listing - action: - goto: /app/teams/visual-audit-team/commerce/products - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Approve Listing service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/listings/scenes/create-product-listing.scene.yaml b/guarantees/marketplace-seller/listings/scenes/create-product-listing.scene.yaml deleted file mode 100644 index 45f91cbd..00000000 --- a/guarantees/marketplace-seller/listings/scenes/create-product-listing.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.listings.create-product-listing.108 -title: Create Product Listing -description: Scene scaffold for guarantee.marketplace-seller.listings.create-product-listing.108. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Product Listing opens the canonical @treeseed/admin full page form workflow. - - Create Product Listing exercises a service journey instead of only loading /app/teams/visual-audit-team/commerce/products. - - Create Product Listing records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Product Listing - action: - goto: /app/teams/visual-audit-team/commerce/products - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Create Product Listing service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/listings/scenes/manage-listing.scene.yaml b/guarantees/marketplace-seller/listings/scenes/manage-listing.scene.yaml deleted file mode 100644 index 005102af..00000000 --- a/guarantees/marketplace-seller/listings/scenes/manage-listing.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.listings.manage-listing.111 -title: Manage Listing -description: Scene scaffold for guarantee.marketplace-seller.listings.manage-listing.111. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Manage Listing opens the canonical @treeseed/admin dashboard read model workflow. - - Manage Listing exercises a service journey instead of only loading /app/teams/visual-audit-team/commerce/products. - - Manage Listing records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Manage Listing - action: - goto: /app/teams/visual-audit-team/commerce/products - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Manage Listing service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/listings/scenes/submit-listing-for-review.scene.yaml b/guarantees/marketplace-seller/listings/scenes/submit-listing-for-review.scene.yaml deleted file mode 100644 index 18e488bc..00000000 --- a/guarantees/marketplace-seller/listings/scenes/submit-listing-for-review.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.listings.submit-listing-for-review.109 -title: Submit Listing For Review -description: Scene scaffold for guarantee.marketplace-seller.listings.submit-listing-for-review.109. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Submit Listing For Review opens the canonical @treeseed/admin record action workflow. - - Submit Listing For Review exercises a service journey instead of only loading /app/teams/visual-audit-team/commerce/products. - - Submit Listing For Review records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Submit Listing For Review - action: - goto: /app/teams/visual-audit-team/commerce/products - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Submit Listing For Review service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/listings/submit-listing-for-review.guarantee.yaml b/guarantees/marketplace-seller/listings/submit-listing-for-review.guarantee.yaml deleted file mode 100644 index b92b9496..00000000 --- a/guarantees/marketplace-seller/listings/submit-listing-for-review.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.listings.submit-listing-for-review.109 -journeyIndex: 109 -type: marketplace-seller -subtype: listings -journey: Submit Listing For Review -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Submit Listing For Review. -status: active -dependencies: - journeys: - - 108 - guarantees: - - guarantee.marketplace-seller.listings.create-product-listing.108 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 108" -scene: - required: true - manifest: ./scenes/submit-listing-for-review.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams/visual-audit-team/commerce/products - componentContract: record-action service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.listings.submit-listing-for-review.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.listings.submit-listing-for-review.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.listings.submit-listing-for-review.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.listings.submit-listing-for-review.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Submit Listing For Review. diff --git a/guarantees/marketplace-seller/onboarding/approve-seller.guarantee.yaml b/guarantees/marketplace-seller/onboarding/approve-seller.guarantee.yaml deleted file mode 100644 index 29cd78b2..00000000 --- a/guarantees/marketplace-seller/onboarding/approve-seller.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.onboarding.approve-seller.107 -journeyIndex: 107 -type: marketplace-seller -subtype: onboarding -journey: Approve Seller -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Approve Seller. -status: active -dependencies: - journeys: - - 106 - guarantees: - - guarantee.marketplace-seller.onboarding.request-seller-setup.106 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 106" -scene: - required: true - manifest: ./scenes/approve-seller.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/market/seller - componentContract: record-action service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.onboarding.approve-seller.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.onboarding.approve-seller.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.onboarding.approve-seller.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.onboarding.approve-seller.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Approve Seller. diff --git a/guarantees/marketplace-seller/onboarding/request-seller-setup.guarantee.yaml b/guarantees/marketplace-seller/onboarding/request-seller-setup.guarantee.yaml deleted file mode 100644 index e76752b1..00000000 --- a/guarantees/marketplace-seller/onboarding/request-seller-setup.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.onboarding.request-seller-setup.106 -journeyIndex: 106 -type: marketplace-seller -subtype: onboarding -journey: Request Seller Setup -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Request Seller Setup. -status: active -dependencies: - journeys: - - 12 - guarantees: - - guarantee.team.team.create-team.012 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 12" -scene: - required: true - manifest: ./scenes/request-seller-setup.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/market/seller - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.onboarding.request-seller-setup.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.onboarding.request-seller-setup.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.onboarding.request-seller-setup.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.onboarding.request-seller-setup.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Request Seller Setup. diff --git a/guarantees/marketplace-seller/onboarding/scenes/approve-seller.scene.yaml b/guarantees/marketplace-seller/onboarding/scenes/approve-seller.scene.yaml deleted file mode 100644 index 2433b90e..00000000 --- a/guarantees/marketplace-seller/onboarding/scenes/approve-seller.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.onboarding.approve-seller.107 -title: Approve Seller -description: Scene scaffold for guarantee.marketplace-seller.onboarding.approve-seller.107. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Approve Seller opens the canonical @treeseed/admin record action workflow. - - Approve Seller exercises a service journey instead of only loading /app/market/seller. - - Approve Seller records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Approve Seller - action: - goto: /app/market/seller - expect: - urlIncludes: /app/market - - id: inspect-service-surface - title: Inspect Approve Seller service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/market -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/onboarding/scenes/request-seller-setup.scene.yaml b/guarantees/marketplace-seller/onboarding/scenes/request-seller-setup.scene.yaml deleted file mode 100644 index b6a9a269..00000000 --- a/guarantees/marketplace-seller/onboarding/scenes/request-seller-setup.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.onboarding.request-seller-setup.106 -title: Request Seller Setup -description: Scene scaffold for guarantee.marketplace-seller.onboarding.request-seller-setup.106. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Request Seller Setup opens the canonical @treeseed/admin full page form workflow. - - Request Seller Setup exercises a service journey instead of only loading /app/market/seller. - - Request Seller Setup records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Request Seller Setup - action: - goto: /app/market/seller - expect: - urlIncludes: /app/market - - id: inspect-service-surface - title: Inspect Request Seller Setup service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/market -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/refunds/issue-refund.guarantee.yaml b/guarantees/marketplace-seller/refunds/issue-refund.guarantee.yaml deleted file mode 100644 index e6620eb6..00000000 --- a/guarantees/marketplace-seller/refunds/issue-refund.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.refunds.issue-refund.114 -journeyIndex: 114 -type: marketplace-seller -subtype: refunds -journey: Issue Refund -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for Issue Refund. -status: active -dependencies: - journeys: - - 112 - guarantees: - - guarantee.marketplace-seller.sales.view-seller-sales.112 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 112" -scene: - required: true - manifest: ./scenes/issue-refund.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams/visual-audit-team/commerce/sales - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.refunds.issue-refund.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.refunds.issue-refund.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.refunds.issue-refund.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.refunds.issue-refund.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for Issue Refund. diff --git a/guarantees/marketplace-seller/refunds/scenes/issue-refund.scene.yaml b/guarantees/marketplace-seller/refunds/scenes/issue-refund.scene.yaml deleted file mode 100644 index 1ebf8e1b..00000000 --- a/guarantees/marketplace-seller/refunds/scenes/issue-refund.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.refunds.issue-refund.114 -title: Issue Refund -description: Scene scaffold for guarantee.marketplace-seller.refunds.issue-refund.114. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Issue Refund opens the canonical @treeseed/admin dashboard read model workflow. - - Issue Refund exercises a service journey instead of only loading /app/teams/visual-audit-team/commerce/sales. - - Issue Refund records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Issue Refund - action: - goto: /app/teams/visual-audit-team/commerce/sales - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Issue Refund service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/sales/scenes/view-seller-sales.scene.yaml b/guarantees/marketplace-seller/sales/scenes/view-seller-sales.scene.yaml deleted file mode 100644 index 21199d10..00000000 --- a/guarantees/marketplace-seller/sales/scenes/view-seller-sales.scene.yaml +++ /dev/null @@ -1,116 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: marketplace-seller.sales.view-seller-sales.112 -title: View Seller Sales -description: Scene scaffold for guarantee.marketplace-seller.sales.view-seller-sales.112. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - View Seller Sales opens the canonical @treeseed/admin dashboard read model workflow. - - View Seller Sales exercises a service journey instead of only loading /app/teams/visual-audit-team/commerce/sales. - - View Seller Sales records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open View Seller Sales - action: - goto: /app/teams/visual-audit-team/commerce/sales - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect View Seller Sales service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/marketplace-seller/sales/view-seller-sales.guarantee.yaml b/guarantees/marketplace-seller/sales/view-seller-sales.guarantee.yaml deleted file mode 100644 index fc7471f0..00000000 --- a/guarantees/marketplace-seller/sales/view-seller-sales.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.marketplace-seller.sales.view-seller-sales.112 -journeyIndex: 112 -type: marketplace-seller -subtype: sales -journey: View Seller Sales -ownerPackage: "@treeseed/admin" -summary: First-pass product guarantee for View Seller Sales. -status: active -dependencies: - journeys: - - 107 - guarantees: - - guarantee.marketplace-seller.onboarding.approve-seller.107 -actors: - allowed: - - buyer - - seller - - market_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 107" -scene: - required: true - manifest: ./scenes/view-seller-sales.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams/visual-audit-team/commerce/sales - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.marketplace-seller.sales.view-seller-sales.api -content: - required: false - verifierRefs: - - admin.marketplace-seller.sales.view-seller-sales.content -audit: - required: true - verifierRefs: - - admin.marketplace-seller.sales.view-seller-sales.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.marketplace-seller.sales.view-seller-sales.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - First-pass product guarantee for View Seller Sales. diff --git a/guarantees/project/agent/create-agent.guarantee.yaml b/guarantees/project/agent/create-agent.guarantee.yaml deleted file mode 100644 index c397e172..00000000 --- a/guarantees/project/agent/create-agent.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.agent.create-agent.057 -journeyIndex: 57 -type: project -subtype: agent -journey: Create Agent -ownerPackage: "@treeseed/admin" -summary: Define a project-owned agent class handler prompts permissions and output contracts; providers supply execution capacity but do not define project agents. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/create-agent.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/agents/new - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.agent.create-agent.api -content: - required: false - verifierRefs: - - admin.project.agent.create-agent.content -audit: - required: true - verifierRefs: - - admin.project.agent.create-agent.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.agent.create-agent.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Define a project-owned agent class handler prompts permissions and output contracts; providers supply execution capacity but do not define project agents. diff --git a/guarantees/project/agent/delete-agent.guarantee.yaml b/guarantees/project/agent/delete-agent.guarantee.yaml deleted file mode 100644 index abd7d6cf..00000000 --- a/guarantees/project/agent/delete-agent.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.agent.delete-agent.059 -journeyIndex: 59 -type: project -subtype: agent -journey: Delete Agent -ownerPackage: "@treeseed/admin" -summary: Remove or disable an agent after checking scheduled workdays assignments and generated artifact ownership. -status: active -dependencies: - journeys: - - 57 - guarantees: - - guarantee.project.agent.create-agent.057 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 57" -scene: - required: true - manifest: ./scenes/delete-agent.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/agents/seed-agent - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.agent.delete-agent.api -content: - required: false - verifierRefs: - - admin.project.agent.delete-agent.content -audit: - required: true - verifierRefs: - - admin.project.agent.delete-agent.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.agent.delete-agent.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Remove or disable an agent after checking scheduled workdays assignments and generated artifact ownership. diff --git a/guarantees/project/agent/edit-agent.guarantee.yaml b/guarantees/project/agent/edit-agent.guarantee.yaml deleted file mode 100644 index be352b2c..00000000 --- a/guarantees/project/agent/edit-agent.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.agent.edit-agent.058 -journeyIndex: 58 -type: project -subtype: agent -journey: Edit Agent -ownerPackage: "@treeseed/admin" -summary: Edit agent configuration and permissions with validation against SDK/agent public contracts; changes should affect future assignments not mutate active runs unsafely. -status: active -dependencies: - journeys: - - 57 - guarantees: - - guarantee.project.agent.create-agent.057 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 57" -scene: - required: true - manifest: ./scenes/edit-agent.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/agents/seed-agent - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.agent.edit-agent.api -content: - required: false - verifierRefs: - - admin.project.agent.edit-agent.content -audit: - required: true - verifierRefs: - - admin.project.agent.edit-agent.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.agent.edit-agent.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Edit agent configuration and permissions with validation against SDK/agent public contracts; changes should affect future assignments not mutate active runs unsafely. diff --git a/guarantees/project/agent/monitor-agent-admin-ui.guarantee.yaml b/guarantees/project/agent/monitor-agent-admin-ui.guarantee.yaml deleted file mode 100644 index 7c811b4e..00000000 --- a/guarantees/project/agent/monitor-agent-admin-ui.guarantee.yaml +++ /dev/null @@ -1,76 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.agent.monitor-agent-admin-ui.140 -journeyIndex: 140 -type: project -subtype: agent -journey: Monitor Agent Admin Ui -ownerPackage: "@treeseed/admin" -surface: admin-ui -summary: "Verify Admin can observe project agents, runtime diagnostics, assignments, mode runs, fallback outputs, usage, TreeDX proxy audit, and settlement evidence without becoming the scheduler." -status: active -dependencies: - journeys: - - 57 - - 60 - guarantees: - - guarantee.project.agent.create-agent.057 - - guarantee.project.agent.monitor-agent.060 -actors: - allowed: - - project_manager - - capacity_operator - - team_owner - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - optional: - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - Blocked by guarantee journey audit: route exists, but the scene does not yet prove a real interactive service journey. - - "Guarantee starts as planned until all verifier refs execute in integrated environments." -scene: - required: false - manifest: ./scenes/monitor-agent-admin-ui.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/runtime - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.agent.monitor.runtime-ui -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.agent.monitor.unauthorized-denied -evidence: - required: - - guarantee_report - - verifier_evidence -notes: - - "Admin monitoring uses project agent pages and /app/capacity/runtime; scheduling remains owned by API and agent runtime." - diff --git a/guarantees/project/agent/scenes/create-agent.scene.yaml b/guarantees/project/agent/scenes/create-agent.scene.yaml deleted file mode 100644 index 9824e70d..00000000 --- a/guarantees/project/agent/scenes/create-agent.scene.yaml +++ /dev/null @@ -1,148 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.agent.create-agent.057 -title: Create Agent -description: Scene scaffold for guarantee.project.agent.create-agent.057. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Agent opens the canonical @treeseed/admin project agent creation workflow. - - A project operator can fill the agent form and queue the local content operation. - - The UI shows reviewable operation feedback after submission. - minimumSteps: 5 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Agent - action: - goto: /app/projects/project-visual-audit-project/agents/new - expect: - urlIncludes: /app/projects/project-visual-audit-project/agents/new - text: New agent - - id: fill-agent-name - title: Fill agent name - action: - fill: - role: textbox - name: Name - value: Guarantee Review Agent {{runShort}} - expect: - text: New agent - - id: fill-agent-description - title: Fill agent description - action: - fill: - role: textbox - name: Description - value: Reviews guarantee evidence and prepares implementation feedback for the TreeSeed market project. - expect: - text: New agent - - id: fill-agent-prompt - title: Fill agent prompt - action: - fill: - role: textbox - name: System prompt - value: Review guarantee evidence, identify concrete UI defects, and produce concise implementation notes. - expect: - text: New agent - - id: submit-agent - title: Submit agent definition - action: - click: - role: button - name: Create agent - expect: - text: Queued. Waiting for the Treeseed operations runner -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/agent/scenes/delete-agent.scene.yaml b/guarantees/project/agent/scenes/delete-agent.scene.yaml deleted file mode 100644 index bd18b41b..00000000 --- a/guarantees/project/agent/scenes/delete-agent.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.agent.delete-agent.059 -title: Delete Agent -description: Scene scaffold for guarantee.project.agent.delete-agent.059. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Agent opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Agent exercises a service journey instead of only loading /app/projects/project-visual-audit-project/agents/seed-agent. - - Delete Agent records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Agent - action: - goto: /app/projects/project-visual-audit-project/agents/seed-agent - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Delete Agent service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/agent/scenes/edit-agent.scene.yaml b/guarantees/project/agent/scenes/edit-agent.scene.yaml deleted file mode 100644 index f91f618e..00000000 --- a/guarantees/project/agent/scenes/edit-agent.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.agent.edit-agent.058 -title: Edit Agent -description: Scene scaffold for guarantee.project.agent.edit-agent.058. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Agent opens the canonical @treeseed/admin full page form workflow. - - Edit Agent exercises a service journey instead of only loading /app/projects/project-visual-audit-project/agents/seed-agent. - - Edit Agent records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Agent - action: - goto: /app/projects/project-visual-audit-project/agents/seed-agent - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Edit Agent service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/agent/scenes/monitor-agent-admin-ui.scene.yaml b/guarantees/project/agent/scenes/monitor-agent-admin-ui.scene.yaml deleted file mode 100644 index 0a3936dc..00000000 --- a/guarantees/project/agent/scenes/monitor-agent-admin-ui.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.agent.monitor-agent-admin-ui.140 -title: Monitor Agent In Admin UI -description: Scene scaffold for project.agent.monitor-agent-admin-ui.140. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Monitor Agent Admin Ui opens the canonical @treeseed/admin record operations workflow. - - Monitor Agent Admin Ui exercises a service journey instead of only loading /app/capacity/runtime. - - Monitor Agent Admin Ui records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Monitor Agent Admin Ui - action: - goto: /app/capacity/runtime - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Monitor Agent Admin Ui service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/allocation/allocate-agent-capacity.guarantee.yaml b/guarantees/project/allocation/allocate-agent-capacity.guarantee.yaml deleted file mode 100644 index eaef1bd2..00000000 --- a/guarantees/project/allocation/allocate-agent-capacity.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.allocation.allocate-agent-capacity.061 -journeyIndex: 61 -type: project -subtype: allocation -journey: Allocate Agent Capacity -ownerPackage: "@treeseed/admin" -summary: Assign team capacity policy to specific project agents or classes; API assignment function uses this policy while providers only enforce local constraints. -status: active -dependencies: - journeys: - - 57 - guarantees: - - guarantee.project.agent.create-agent.057 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 57" -scene: - required: true - manifest: ./scenes/allocate-agent-capacity.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/allocation/projects/seed-project - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.allocation.allocate-agent-capacity.api -content: - required: false - verifierRefs: - - admin.project.allocation.allocate-agent-capacity.content -audit: - required: true - verifierRefs: - - admin.project.allocation.allocate-agent-capacity.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.allocation.allocate-agent-capacity.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Assign team capacity policy to specific project agents or classes; API assignment function uses this policy while providers only enforce local constraints. diff --git a/guarantees/project/allocation/allocate-project-capacity.guarantee.yaml b/guarantees/project/allocation/allocate-project-capacity.guarantee.yaml deleted file mode 100644 index 563990f9..00000000 --- a/guarantees/project/allocation/allocate-project-capacity.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.allocation.allocate-project-capacity.037 -journeyIndex: 37 -type: project -subtype: allocation -journey: Allocate Project Capacity -ownerPackage: "@treeseed/admin" -summary: Define team capacity policy or allocation sets for the project; this is policy configuration and must not become provider-side scheduling. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/allocate-project-capacity.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/allocation/projects/seed-project - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.allocation.allocate-project-capacity.api -content: - required: false - verifierRefs: - - admin.project.allocation.allocate-project-capacity.content -audit: - required: true - verifierRefs: - - admin.project.allocation.allocate-project-capacity.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.allocation.allocate-project-capacity.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Define team capacity policy or allocation sets for the project; this is policy configuration and must not become provider-side scheduling. diff --git a/guarantees/project/allocation/scenes/allocate-agent-capacity.scene.yaml b/guarantees/project/allocation/scenes/allocate-agent-capacity.scene.yaml deleted file mode 100644 index 63ef8476..00000000 --- a/guarantees/project/allocation/scenes/allocate-agent-capacity.scene.yaml +++ /dev/null @@ -1,120 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.allocation.allocate-agent-capacity.061 -title: Allocate Agent Capacity -description: Scene scaffold for guarantee.project.allocation.allocate-agent-capacity.061. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Allocate Agent Capacity opens the canonical @treeseed/admin record operations workflow. - - Allocate Agent Capacity exercises a service journey instead of only loading /app/capacity/allocation/projects/seed-project. - - Allocate Agent Capacity records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Allocate Agent Capacity - action: - goto: /app/capacity/allocation/projects/seed-project - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Allocate Agent Capacity service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/allocation/scenes/allocate-project-capacity.scene.yaml b/guarantees/project/allocation/scenes/allocate-project-capacity.scene.yaml deleted file mode 100644 index f1bc61a9..00000000 --- a/guarantees/project/allocation/scenes/allocate-project-capacity.scene.yaml +++ /dev/null @@ -1,120 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.allocation.allocate-project-capacity.037 -title: Allocate Project Capacity -description: Scene scaffold for guarantee.project.allocation.allocate-project-capacity.037. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Allocate Project Capacity opens the canonical @treeseed/admin record operations workflow. - - Allocate Project Capacity exercises a service journey instead of only loading /app/capacity/allocation/projects/seed-project. - - Allocate Project Capacity records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project - - key: capacity-provider.primary - kind: capacity-provider -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Allocate Project Capacity - action: - goto: /app/capacity/allocation/projects/seed-project - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Allocate Project Capacity service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/book/archive-book.guarantee.yaml b/guarantees/project/book/archive-book.guarantee.yaml new file mode 100644 index 00000000..34eaf5d1 --- /dev/null +++ b/guarantees/project/book/archive-book.guarantee.yaml @@ -0,0 +1,28 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.project.book.delete-book.067 +journeyIndex: 67 +type: project +subtype: book +journey: Archive And Restore Book +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Archive and restore a book only after showing page, backlink, and pack dependencies. +status: active +dependencies: { journeys: [65], guarantees: [guarantee.project.book.create-book.065] } +actors: { allowed: [project_manager], forbidden: [anonymous_user, non_member, project_viewer, project_contributor] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [security, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.book-lifecycle] } +scene: { required: true, manifest: scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: destructive dependency review } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.run-correlated, api.knowledge.lifecycle.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content, core.knowledge.starlight-reader] } +audit: { required: true, verifierRefs: [api.knowledge.lifecycle.run-correlated, api.knowledge.collection.run-correlated] } +negativeCases: + - { id: anonymous-lifecycle-denied, actor: anonymous_user, sceneManifest: scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-lifecycle-denied, actor: non_member, sceneManifest: scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: readonly-lifecycle-denied, actor: project_viewer, sceneManifest: scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.control-plane] } + - { id: contributor-lifecycle-denied, actor: project_contributor, sceneManifest: scenes/negative/contributor-knowledge-lifecycle.scene.yaml, executionKey: admin.knowledge.negative.contributor, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } +notes: [The shared execution proves dependency blocking followed by independently reviewed archive and restore publications.] +run: { requiredForRelease: true } diff --git a/guarantees/project/book/create-book.guarantee.yaml b/guarantees/project/book/create-book.guarantee.yaml index 12c9dc10..604c9eee 100644 --- a/guarantees/project/book/create-book.guarantee.yaml +++ b/guarantees/project/book/create-book.guarantee.yaml @@ -5,69 +5,24 @@ type: project subtype: book journey: Create Book ownerPackage: "@treeseed/admin" -summary: Create a Knowledge Hub book through the SDK content model and TreeDX; books organize project knowledge rather than serving as package docs only. +surface: admin-ui +summary: Create a repository-native book through rendered controls and a correlated TreeDX authoring workspace. status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/create-book.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/knowledge/books - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.book.create-book.api -content: - required: true - verifierRefs: - - admin.project.book.create-book.content -audit: - required: true - verifierRefs: - - admin.project.book.create-book.audit +actors: { allowed: [project_contributor, project_manager], forbidden: [anonymous_user, non_member, project_viewer] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.book-authoring, knowledge.review-publication] } +scene: { required: true, manifest: scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: "/app/projects/[projectId]/books", componentContract: knowledge authoring workflow } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content] } +audit: { required: true, verifierRefs: [api.knowledge.run-correlated] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.book.create-book.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id + - { id: anonymous-authoring-denied, actor: anonymous_user, sceneManifest: scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-authoring-denied, actor: non_member, sceneManifest: scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: readonly-authoring-denied, actor: project_viewer, sceneManifest: scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } notes: - - Create a Knowledge Hub book through the SDK content model and TreeDX; books organize project knowledge rather than serving as package docs only. + - The shared execution performs the mutation through rendered controls and publishes run-scoped correlation identifiers. + - July evidence remains inadmissible because it reused an unrelated read-only role verifier. +run: { requiredForRelease: true } diff --git a/guarantees/project/book/delete-book.guarantee.yaml b/guarantees/project/book/delete-book.guarantee.yaml deleted file mode 100644 index b08a8c59..00000000 --- a/guarantees/project/book/delete-book.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.book.delete-book.067 -journeyIndex: 67 -type: project -subtype: book -journey: Delete Book -ownerPackage: "@treeseed/admin" -summary: Delete or archive a book with checks for pages links downloads and library indexes. -status: active -dependencies: - journeys: - - 65 - guarantees: - - guarantee.project.book.create-book.065 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 65" -scene: - required: true - manifest: ./scenes/delete-book.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/knowledge/books/seed-book - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.book.delete-book.api -content: - required: true - verifierRefs: - - admin.project.book.delete-book.content -audit: - required: true - verifierRefs: - - admin.project.book.delete-book.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.book.delete-book.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Delete or archive a book with checks for pages links downloads and library indexes. diff --git a/guarantees/project/book/download-book.guarantee.yaml b/guarantees/project/book/download-book.guarantee.yaml deleted file mode 100644 index f279a7e7..00000000 --- a/guarantees/project/book/download-book.guarantee.yaml +++ /dev/null @@ -1,75 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.book.download-book.070 -journeyIndex: 70 -type: project -subtype: book -journey: Download Book -ownerPackage: "@treeseed/admin" -summary: Export a book or selected pages from TreeDX-backed content; depends on an existing book and at least one available page. -status: active -dependencies: - journeys: - - 65 - - 69 - guarantees: - - guarantee.project.book.create-book.065 - - guarantee.project.knowledge.create-book-page.069 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 65, 69" -scene: - required: true - manifest: ./scenes/download-book.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/knowledge/books/seed-book - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.book.download-book.api -content: - required: true - verifierRefs: - - admin.project.book.download-book.content -audit: - required: true - verifierRefs: - - admin.project.book.download-book.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.book.download-book.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Export a book or selected pages from TreeDX-backed content; depends on an existing book and at least one available page. diff --git a/guarantees/project/book/edit-book.guarantee.yaml b/guarantees/project/book/edit-book.guarantee.yaml index b1e3e265..f69b8e85 100644 --- a/guarantees/project/book/edit-book.guarantee.yaml +++ b/guarantees/project/book/edit-book.guarantee.yaml @@ -5,69 +5,23 @@ type: project subtype: book journey: Edit Book ownerPackage: "@treeseed/admin" -summary: Edit book metadata ordering and visibility through TreeDX-backed content operations. +surface: admin-ui +summary: Edit book metadata, ordering, visibility, and relationships through a versioned TreeDX workspace. status: active -dependencies: - journeys: - - 65 - guarantees: - - guarantee.project.book.create-book.065 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 65" -scene: - required: true - manifest: ./scenes/edit-book.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/knowledge/books/seed-book - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.book.edit-book.api -content: - required: true - verifierRefs: - - admin.project.book.edit-book.content -audit: - required: true - verifierRefs: - - admin.project.book.edit-book.audit +dependencies: { journeys: [65], guarantees: [guarantee.project.book.create-book.065] } +actors: { allowed: [project_contributor, project_manager], forbidden: [anonymous_user, non_member, project_viewer] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.book-authoring] } +scene: { required: true, manifest: scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: conflict-safe knowledge editor } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content] } +audit: { required: true, verifierRefs: [api.knowledge.run-correlated] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.book.edit-book.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Edit book metadata ordering and visibility through TreeDX-backed content operations. + - { id: anonymous-edit-denied, actor: anonymous_user, sceneManifest: scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-edit-denied, actor: non_member, sceneManifest: scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: readonly-edit-denied, actor: project_viewer, sceneManifest: scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } +notes: [The shared execution proves validation, revision after requested changes, exact TreeDX commit publication, and durable reload state.] +run: { requiredForRelease: true } diff --git a/guarantees/project/book/scenes/author-publish-book.scene.yaml b/guarantees/project/book/scenes/author-publish-book.scene.yaml new file mode 100644 index 00000000..8e5afefd --- /dev/null +++ b/guarantees/project/book/scenes/author-publish-book.scene.yaml @@ -0,0 +1,705 @@ +schemaVersion: treeseed.scene/v1 +id: project.knowledge.author-publish +title: Author, review, publish, read, and package knowledge +description: Creates a run-scoped book and page through the rendered workbench, uses a different reviewer, publishes atomically, searches TreeDX, opens Starlight, and builds an immutable pack. +audience: [operator, evaluator] +journey: + kind: service + proves: [knowledge.book-authoring, knowledge.book-lifecycle, knowledge.page-authoring, knowledge.page-lifecycle, knowledge.relationships, knowledge.review-publication, knowledge.library, knowledge.reader, knowledge.packs] + minimumSteps: 20 + requiresInteractiveAction: true + producesState: + - key: knowledge.published + kind: marker + value: { bookId: "guarantee-book-{{runShort}}-{{deviceId}}", pageId: "guarantee-page-{{runShort}}-{{deviceId}}" } + - key: knowledge.platform-admin-session + kind: browser-storage +mode: { test: true, demo: true, training: true } +target: + app: market + environment: local + baseUrl: auto + browser: chromium + viewport: { width: 1600, height: 900 } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, orientation: portrait, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: platform_admin, fixtureRoles: [knowledge_reviewer], required: true } +artifacts: { trace: true, video: true, screenshots: true, fullPageScreenshots: false, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-workbench + title: Open the active-team knowledge workbench + action: { goto: /app/knowledge } + expect: { urlIncludes: /app/knowledge, visible: [{ scene: app-shell }] } + - id: select-central-team + title: Scope knowledge work to the central TreeSeed team + action: { select: { css: ':nth-match([data-team-switcher] select[name="teamId"], 1)', internal: true, label: TreeSeed } } + expect: { urlIncludes: /app/knowledge } + - id: await-central-team-navigation + title: Let the progressive-enhancement team selection finish + action: { pause: { mode: timed, durationSeconds: 1 } } + expect: { urlIncludes: /app/knowledge } + - id: reload-central-library + title: Load the central federated library after explicit selection + action: { goto: /app/knowledge } + expect: { text: Knowledge repositories, visible: [{ css: '[data-project-name="TreeSeed Admin"]', internal: true }] } + - id: choose-admin-project + title: Author in the Admin repository through its visible project control + action: { click: { css: '[data-project-name="TreeSeed Admin"] a[href^="/app/knowledge?project="]', internal: true } } + expect: { text: Start an authoring workspace } + - id: start-workspace + title: Create an isolated TreeDX workspace + action: { click: { css: '[data-scene="knowledge.workspace.start"] button[type="submit"]', internal: true } } + expect: { text: Start an authoring workspace } + - id: await-workspace-editor + title: Wait for the federated workspace editor to finish loading + action: { pause: { mode: timed, durationSeconds: 8 } } + expect: { urlIncludes: workspace=, visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: reject-empty-book + title: Reject an incomplete book without a repository mutation + action: { select: { css: '[data-scene="knowledge.editor.form"] select[name="kind"]', internal: true, label: Book } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: submit-empty-book + title: Exercise adjacent native validation + action: { click: { role: button, name: Save draft } } + expect: { urlIncludes: workspace=, notText: Draft saved. } + - id: fill-book-id + title: Enter a stable run-scoped book identifier + action: { fill: { css: 'input[name="id"]', internal: true, value: "guarantee-book-{{runShort}}-{{deviceId}}" } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-book-slug + title: Enter the canonical book slug + action: { fill: { css: 'input[name="slug"]', internal: true, value: "guarantee-book-{{runShort}}-{{deviceId}}" } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-book-title + title: Enter the human book title + action: { fill: { role: textbox, name: Title, value: "Guarantee Book {{runShort}} {{deviceId}}" } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-book-summary + title: Explain the book in the federated catalog + action: { fill: { role: textbox, name: Summary, value: "Run-scoped knowledge proving repository authoring and atomic publication." } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-book-description + title: Add complete book metadata + action: { fill: { role: textbox, name: Description, value: "A real acceptance book created in TreeDX and reviewed before publication." } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: save-book + title: Save the book through the enhanced form + action: { click: { role: button, name: Save draft } } + expect: { text: Draft saved., visible: [{ css: '[data-ts-toast-id][data-tone="success"]', internal: true }] } + - id: choose-page + title: Add a page to the same isolated workspace + action: { select: { css: '[data-scene="knowledge.editor.form"] select[name="kind"]', internal: true, label: Knowledge page } } + expect: { visible: [{ css: 'input[name="bookId"]', internal: true }] } + - id: fill-page-fields + title: Enter page ownership + action: { fill: { css: 'input[name="bookId"]', internal: true, value: "guarantee-book-{{runShort}}-{{deviceId}}" } } + expect: { visible: [{ css: 'textarea[name="bodyMarkdown"]', internal: true }] } + - id: fill-page-id + title: Enter the stable page identifier + action: { fill: { css: 'input[name="id"]', internal: true, value: "guarantee-page-{{runShort}}-{{deviceId}}" } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-page-slug + title: Enter the ordered page slug + action: { fill: { css: 'input[name="slug"]', internal: true, value: getting-started } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-page-title + title: Enter the page title + action: { fill: { role: textbox, name: Title, value: Getting started } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-page-summary + title: Enter the page summary + action: { fill: { role: textbox, name: Summary, value: "A searchable page with safe fenced TypeScript examples." } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: fill-page-markdown + title: Author Markdown containing fenced export syntax + action: + fill: + css: 'textarea[name="bodyMarkdown"]' + internal: true + value: "# Getting started\n\nThis page is published from an exact TreeDX commit.\n\n```ts\nexport const safeExample = true;\n```" + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: search-related-note + title: Find a real repository note through the TreeDX relationship graph + action: { fill: { css: '[data-knowledge-relation-field="relatedNoteIds"] input[type="search"]', internal: true, value: "knowledge authoring traceability" } } + expect: + visible: + - { css: '[data-knowledge-relation-results="relatedNoteIds"] button:has-text("Knowledge authoring traceability")', internal: true } + - id: link-related-note + title: Link the note through the rendered relationship picker + action: { click: { css: '[data-knowledge-relation-results="relatedNoteIds"] button:has-text("Knowledge authoring traceability")', internal: true } } + expect: { visible: [{ css: '[data-knowledge-relation-field="relatedNoteIds"] .ts-knowledge-relations__chip:has-text("Knowledge authoring traceability")', internal: true }] } + - id: search-related-question + title: Find a real repository question through the TreeDX relationship graph + action: { fill: { css: '[data-knowledge-relation-field="relatedQuestionIds"] input[type="search"]', internal: true, value: "knowledge publication stay trustworthy" } } + expect: + visible: + - { css: '[data-knowledge-relation-results="relatedQuestionIds"] button:has-text("How should knowledge publication stay trustworthy?")', internal: true } + - id: link-related-question + title: Link the question through the rendered relationship picker + action: { click: { css: '[data-knowledge-relation-results="relatedQuestionIds"] button:has-text("How should knowledge publication stay trustworthy?")', internal: true } } + expect: { visible: [{ css: '[data-knowledge-relation-field="relatedQuestionIds"] .ts-knowledge-relations__chip:has-text("How should knowledge publication stay trustworthy?")', internal: true }] } + - id: submit-knowledge-review + title: Save and submit the book and page for independent review + action: { click: { role: button, name: Submit for review } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: await-review-navigation + title: Wait for the TreeDX commit and submitted review queue to finish loading + action: { pause: { mode: timed, durationSeconds: 10 } } + expect: { urlIncludes: view=reviews } + - id: prove-self-review-denied + title: Prove the author cannot approve the submission + action: { goto: /app/knowledge?view=reviews } + expect: + text: A different authorized reviewer must decide this submission. + visible: + - { css: '[data-review-status="open"][data-review-decision="forbidden"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"]', internal: true } + - id: sign-out-author + title: End the author session before independent review + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in, text: Sign in } + - id: enter-reviewer-email + title: Enter the independent reviewer's identity + action: { fill: { role: textbox, name: Email or username, value: visual.knowledge-reviewer@treeseed.io } } + expect: { text: Sign in } + - id: enter-reviewer-password + title: Enter the independent reviewer's fixture password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: sign-in-reviewer + title: Authenticate as the different authorized reviewer + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app, visible: [{ scene: app-shell }] } + - id: open-review-queue + title: Open the exact submitted review + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.decision"]', internal: true }] } + - id: enter-review-comment + title: Attach an actionable comment to the exact changed file + action: { fill: { css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] form:has(input[value="review-comment"]) textarea[name="body"]', internal: true, value: "Clarify that this revision completed independent review." } } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] form:has(input[value="review-comment"])', internal: true }] } + - id: add-review-comment + title: Persist the line-aware review observation + action: { click: { css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] form:has(input[value="review-comment"]) button[type="submit"]', internal: true } } + expect: { text: Review comment added. } + - id: enter-request-change-notes + title: Explain the requested revision + action: { fill: { css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.decision"] textarea[name="notes"]', internal: true, value: "Address the review comment and resubmit the same workspace." } } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.decision"]', internal: true }] } + - id: request-review-changes + title: Return the exact submission to its author + action: { click: { css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.decision"] button[value="request-changes"]', internal: true } } + expect: { text: Review decision recorded. } + - id: sign-out-reviewer-for-revision + title: End the reviewer session before author revision + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in, text: Sign in } + - id: enter-revision-author-email + title: Return to the original knowledge author + action: { fill: { role: textbox, name: Email or username, value: visual.platform-admin@treeseed.io } } + expect: { text: Sign in } + - id: enter-revision-author-password + title: Enter the author fixture password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: sign-in-revision-author + title: Authenticate the original author + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app, visible: [{ scene: app-shell }] } + - id: open-requested-changes + title: Open the exact returned review + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="changes-requested"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"]', internal: true }] } + - id: resolve-review-comment + title: Resolve the review comment as the workspace author + action: { click: { css: '[data-review-status="changes-requested"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] form:has(input[value="resolve-review-comment"]) button[type="submit"]', internal: true } } + expect: { text: Review comment resolved. } + - id: open-revision-draft + title: Return to the same recoverable TreeDX workspace + action: { click: { css: '[data-review-status="changes-requested"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("View draft")', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: revise-book-summary + title: Apply the requested clarification + action: { fill: { role: textbox, name: Summary, value: "Run-scoped knowledge proving repository authoring, revision, independent review, and atomic publication." } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: resubmit-knowledge-review + title: Save and resubmit the revised workspace + action: { click: { role: button, name: Submit for review } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: await-revision-navigation + title: Wait for the revised commit and review queue + action: { pause: { mode: timed, durationSeconds: 8 } } + expect: { urlIncludes: view=reviews } + - id: sign-out-revision-author + title: End the author session before the second review + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in, text: Sign in } + - id: enter-returning-reviewer-email + title: Return to the independent reviewer + action: { fill: { role: textbox, name: Email or username, value: visual.knowledge-reviewer@treeseed.io } } + expect: { text: Sign in } + - id: enter-returning-reviewer-password + title: Enter the reviewer fixture password again + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: sign-in-returning-reviewer + title: Authenticate the reviewer for the revised submission + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app, visible: [{ scene: app-shell }] } + - id: open-revised-review + title: Open the new exact review record + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.decision"]', internal: true }] } + - id: approve-review + title: Approve the exact TreeDX diff as a different user + action: { click: { css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.decision"] button[value="approve"]', internal: true } } + expect: { text: Review decision recorded. } + - id: reload-approved-review + title: Reload the durable review state before publication + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="approved"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.publish"]', internal: true }] } + - id: publish-approved-review + title: Queue atomic publication through the rendered control + action: { click: { css: '[data-review-status="approved"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}"] [data-scene="knowledge.review.publish"] button[type="submit"]', internal: true } } + expect: { text: Approved knowledge publication queued. } + - id: await-publication + title: Wait for Git, TreeDX graph, object, and manifest publication + action: { waitForOperation: { kind: "knowledge:publish_review", source: linked, status: [succeeded], timeoutSeconds: 180, pollIntervalSeconds: 2 } } + expect: { urlIncludes: /app/knowledge } + - id: sign-out-reviewer + title: End the review-only session after its independent decision + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in, text: Sign in } + - id: enter-platform-admin-email + title: Return to the authorized TreeSeed team administrator + action: { fill: { role: textbox, name: Email or username, value: visual.platform-admin@treeseed.io } } + expect: { text: Sign in } + - id: enter-platform-admin-password + title: Enter the platform administrator fixture password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: sign-in-platform-admin + title: Authenticate as a reader and pack builder for the central team + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app, visible: [{ scene: app-shell }] } + - id: search-library + title: Search the federated library through TreeDX + action: { goto: /books } + expect: { visible: [{ css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"]', internal: true }] } + - id: enter-search-query + title: Search for the published run book + action: { fill: { role: searchbox, name: Search books, value: "Guarantee Book {{runShort}}" } } + expect: { visible: [{ css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"]', internal: true }] } + - id: open-starlight-book + title: Open the published book overview + action: { click: { css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("Open book")', internal: true } } + expect: { urlIncludes: /books/guarantee-book-, text: Getting started } + - id: open-starlight-page + title: Render the exact page revision in Starlight + action: { click: { text: Getting started } } + expect: { urlIncludes: /getting-started, text: This page is published from an exact TreeDX commit. } + - id: open-contextual-knowledge + title: Resolve published book knowledge in the shared help dialog + action: { click: { role: button, name: Open help } } + expect: + text: TreeSeed Help + visible: + - { css: '[data-ts-help-dialog][open] .ts-help-article__body:has-text("This page is published from an exact TreeDX commit.")', internal: true } + - { css: '[data-ts-help-dialog][open] a:has-text("Open full page")[href*="/guarantee-book-{{runShort}}-{{deviceId}}/getting-started"]', internal: true } + - id: search-contextual-knowledge + title: Search the federated knowledge graph from contextual help + action: { fill: { role: searchbox, name: Search help, value: "Guarantee Book {{runShort}}" } } + expect: { visible: [{ css: '[data-ts-help-search-results] button[data-ts-help-knowledge-page-id="guarantee-page-{{runShort}}-{{deviceId}}"]', internal: true }] } + - id: choose-contextual-search-result + title: Load the exact authorized search result without leaving the reader + action: { click: { css: '[data-ts-help-search-results] button[data-ts-help-knowledge-page-id="guarantee-page-{{runShort}}-{{deviceId}}"]', internal: true } } + expect: + urlIncludes: /getting-started + visible: [{ css: '[data-ts-help-dialog][open] .ts-help-article__body:has-text("This page is published from an exact TreeDX commit.")', internal: true }] + - id: return-to-packs + title: Open pack creation for the same publication + action: { goto: /app/knowledge?view=packs } + expect: { visible: [{ css: '[data-scene="knowledge.pack.build"]', internal: true }] } + - id: select-run-book + title: Select exactly the run-created book + action: { click: { css: '[data-scene="knowledge.pack.build"] input[value="guarantee-book-{{runShort}}-{{deviceId}}"]', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.pack.build"] input[value="guarantee-book-{{runShort}}-{{deviceId}}"]:checked', internal: true }] } + - id: build-pack + title: Build the immutable one-book artifact + action: { click: { css: '[data-scene="knowledge.pack.build"] button[type="submit"]', internal: true } } + expect: { text: Knowledge-pack build queued. } + - id: await-pack + title: Wait for immutable artifact generation + action: { waitForOperation: { kind: "knowledge:build_pack", source: linked, status: [succeeded], timeoutSeconds: 120, pollIntervalSeconds: 2 } } + expect: { urlIncludes: view=packs } + - id: verify-pack-download + title: Reload and prove the pack is downloadable + action: { goto: /app/knowledge?view=packs } + expect: + visible: + - { css: 'article[data-knowledge-pack-book-ids="guarantee-book-{{runShort}}-{{deviceId}}"][data-knowledge-pack-latest="true"] a:has-text("Download")', internal: true } + - id: name-selected-collection + title: Name a repeatable selected-book collection + action: { fill: { css: 'form:has(input[name="action"][value="create-collection"]) input[name="name"]', internal: true, value: "Guarantee Collection {{runShort}} {{deviceId}}" } } + expect: { visible: [{ css: 'form:has(input[name="action"][value="create-collection"])', internal: true }] } + - id: select-run-book-for-collection + title: Add the run-created book to the collection + action: { click: { css: 'form:has(input[name="action"][value="create-collection"]) input[value="guarantee-book-{{runShort}}-{{deviceId}}"]', internal: true } } + expect: { visible: [{ css: 'form:has(input[name="action"][value="create-collection"]) input[value="guarantee-book-{{runShort}}-{{deviceId}}"]:checked', internal: true }] } + - id: select-platform-book-for-collection + title: Add a second explicit platform book without expanding relationship scope + action: { click: { css: 'form:has(input[name="action"][value="create-collection"]) input[value="treeseed-accounts-and-identity"]', internal: true } } + expect: { visible: [{ css: 'form:has(input[name="action"][value="create-collection"]) input[value="treeseed-accounts-and-identity"]:checked', internal: true }] } + - id: save-selected-collection + title: Persist the deliberate book selection + action: { click: { css: 'form:has(input[name="action"][value="create-collection"]) button[type="submit"]', internal: true } } + expect: { text: Book collection saved. } + - id: reload-selected-collection + title: Reload the durable collection + action: { goto: /app/knowledge?view=packs } + expect: { text: "Guarantee Collection {{runShort}} {{deviceId}}" } + - id: build-selected-collection + title: Build the exact saved collection through its rendered action + action: { click: { css: 'article:has-text("Guarantee Collection {{runShort}} {{deviceId}}") button:has-text("Build latest")', internal: true } } + expect: { text: Knowledge-pack build queued. } + - id: await-selected-pack + title: Wait for selected-book artifact generation + action: { waitForOperation: { kind: "knowledge:build_pack", source: linked, status: [succeeded], timeoutSeconds: 120, pollIntervalSeconds: 2 } } + expect: { urlIncludes: view=packs } + - id: verify-selected-pack + title: Prove the selected-book pack is complete and downloadable + action: { goto: /app/knowledge?view=packs } + expect: + visible: + - { css: 'article[data-knowledge-pack-book-ids~="guarantee-book-{{runShort}}-{{deviceId}}"][data-knowledge-pack-book-ids~="treeseed-accounts-and-identity"][data-knowledge-pack-latest="true"] a:has-text("Download")', internal: true } + - id: open-book-lifecycle-blockers + title: Open lifecycle controls for the exact run-created book + action: { goto: /app/knowledge } + expect: { visible: [{ css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("Manage")', internal: true }] } + - id: manage-blocked-book + title: Inspect the book through its rendered management control + action: { click: { css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("Manage")', internal: true } } + expect: + visible: + - { css: '[data-scene="knowledge.lifecycle"][data-knowledge-kind="book"][data-knowledge-blocker-count="2"]', internal: true } + - id: disclose-blocked-book-archive + title: Expose the disabled archive action after reviewing its dependencies + action: { click: { css: '[data-scene="knowledge.lifecycle.form"] summary:has-text("Archive book")', internal: true } } + expect: + visible: + - { css: '[data-scene="knowledge.lifecycle.form"] button:has-text("Prepare archive for review"):disabled', internal: true } + - id: remove-run-collection + title: Remove the saved collection through its rendered destructive control + action: { goto: /app/knowledge?view=packs } + expect: { visible: [{ css: 'article:has-text("Guarantee Collection {{runShort}} {{deviceId}}") button:has-text("Delete")', internal: true }] } + - id: delete-run-collection + title: Resolve the saved-collection blocker + action: { click: { css: 'article:has-text("Guarantee Collection {{runShort}} {{deviceId}}") button:has-text("Delete")', internal: true } } + expect: { text: Book collection deleted. } + - id: open-run-page-outline + title: Open the run book outline before archiving its page + action: { goto: /app/knowledge } + expect: { visible: [{ css: 'details[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] summary', internal: true }] } + - id: expand-run-page-outline + title: Expand the exact run book outline + action: { click: { css: 'details[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] summary', internal: true } } + expect: { visible: [{ css: '[data-page-id="guarantee-page-{{runShort}}-{{deviceId}}"] a:has-text("Edit page")', internal: true }] } + - id: manage-run-page-lifecycle + title: Open the page lifecycle controls + action: { click: { css: '[data-page-id="guarantee-page-{{runShort}}-{{deviceId}}"] a:has-text("Edit page")', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.lifecycle"][data-knowledge-kind="page"][data-knowledge-blocker-count="0"]', internal: true }] } + - id: disclose-page-archive + title: Open the deliberate page archive confirmation + action: { click: { css: '[data-scene="knowledge.lifecycle.form"] summary:has-text("Archive page")', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.lifecycle.form"] button:has-text("Prepare archive for review")', internal: true }] } + - id: prepare-page-archive + title: Create the page archive draft through the rendered control + action: { click: { css: '[data-scene="knowledge.lifecycle.form"] button:has-text("Prepare archive for review")', internal: true } } + expect: { urlIncludes: workspace=, visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: submit-page-archive + title: Submit the archived page document for independent review + action: { click: { role: button, name: Submit for review } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: await-page-archive-review-navigation + title: Wait for the archived page review queue to finish loading + action: { pause: { mode: timed, durationSeconds: 10 } } + expect: { urlIncludes: view=reviews } + - id: sign-out-page-archive-author + title: End the archive author's session + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in } + - id: sign-in-page-archive-reviewer + title: Enter the independent reviewer identity for page archive + action: { fill: { role: textbox, name: Email or username, value: visual.knowledge-reviewer@treeseed.io } } + expect: { text: Sign in } + - id: password-page-archive-reviewer + title: Enter the reviewer password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: authenticate-page-archive-reviewer + title: Authenticate the page archive reviewer + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app } + - id: approve-page-archive + title: Approve the exact archived page diff + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] [data-scene="knowledge.review.decision"]', internal: true }] } + - id: decide-page-archive + title: Record independent approval for the page archive + action: { click: { css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] button[value="approve"]', internal: true } } + expect: { text: Review decision recorded. } + - id: reload-page-archive + title: Reload the durable page archive approval + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="approved"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] [data-scene="knowledge.review.publish"]', internal: true }] } + - id: publish-page-archive + title: Publish the approved page archive + action: { click: { css: '[data-review-status="approved"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] [data-scene="knowledge.review.publish"] button', internal: true } } + expect: { text: Approved knowledge publication queued. } + - id: await-page-archive + title: Wait for atomic archived-page publication + action: { waitForOperation: { kind: "knowledge:publish_review", source: linked, status: [succeeded], timeoutSeconds: 180, pollIntervalSeconds: 2 } } + expect: { urlIncludes: /app/knowledge } + - id: return-to-book-author + title: Sign out the reviewer before the book archive mutation + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in } + - id: enter-book-author + title: Return to the authorized lifecycle author + action: { fill: { role: textbox, name: Email or username, value: visual.platform-admin@treeseed.io } } + expect: { text: Sign in } + - id: enter-book-author-password + title: Enter the lifecycle author's password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: authenticate-book-author + title: Authenticate the book lifecycle author + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app } + - id: reopen-book-lifecycle + title: Reopen the exact book after resolving all blockers + action: { goto: /app/knowledge } + expect: { visible: [{ css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("Manage")', internal: true }] } + - id: manage-unblocked-book + title: Prove the book archive is now unblocked + action: { click: { css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("Manage")', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.lifecycle"][data-knowledge-kind="book"][data-knowledge-blocker-count="0"]', internal: true }] } + - id: disclose-book-archive + title: Open the deliberate book archive confirmation + action: { click: { css: '[data-scene="knowledge.lifecycle.form"] summary:has-text("Archive book")', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.lifecycle.form"] button:has-text("Prepare archive for review")', internal: true }] } + - id: prepare-book-archive + title: Create the book archive draft through the rendered control + action: { click: { css: '[data-scene="knowledge.lifecycle.form"] button:has-text("Prepare archive for review")', internal: true } } + expect: { urlIncludes: workspace=, visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: submit-book-archive + title: Submit the archived book for independent review + action: { click: { role: button, name: Submit for review } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: await-book-archive-review-navigation + title: Wait for the archived book review queue to finish loading + action: { pause: { mode: timed, durationSeconds: 10 } } + expect: { urlIncludes: view=reviews } + - id: sign-out-book-archive-author + title: End the book archive author's session + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in } + - id: enter-book-archive-reviewer + title: Enter the independent book archive reviewer + action: { fill: { role: textbox, name: Email or username, value: visual.knowledge-reviewer@treeseed.io } } + expect: { text: Sign in } + - id: password-book-archive-reviewer + title: Enter the reviewer password for book archive + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: authenticate-book-archive-reviewer + title: Authenticate the book archive reviewer + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app } + - id: approve-book-archive + title: Open the exact book archive review + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] [data-scene="knowledge.review.decision"]', internal: true }] } + - id: decide-book-archive + title: Approve the book archive as a different user + action: { click: { css: '[data-review-status="open"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] button[value="approve"]', internal: true } } + expect: { text: Review decision recorded. } + - id: reload-book-archive + title: Reload the durable book archive approval + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="approved"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] [data-scene="knowledge.review.publish"]', internal: true }] } + - id: publish-book-archive + title: Publish the approved book archive + action: { click: { css: '[data-review-status="approved"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] [data-scene="knowledge.review.publish"] button', internal: true } } + expect: { text: Approved knowledge publication queued. } + - id: await-book-archive + title: Wait for atomic archived-book publication + action: { waitForOperation: { kind: "knowledge:publish_review", source: linked, status: [succeeded], timeoutSeconds: 180, pollIntervalSeconds: 2 } } + expect: { urlIncludes: /app/knowledge } + - id: sign-out-book-archive-reviewer + title: End the reviewer session before restoration + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in } + - id: enter-restore-author + title: Return to the lifecycle author for restoration + action: { fill: { role: textbox, name: Email or username, value: visual.platform-admin@treeseed.io } } + expect: { text: Sign in } + - id: password-restore-author + title: Enter the restore author's password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: authenticate-restore-author + title: Authenticate the restore author + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app } + - id: open-archived-book + title: Open the archived book management surface + action: { goto: /app/knowledge } + expect: { visible: [{ css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("Manage")', internal: true }] } + - id: manage-archived-book + title: Open the archived book restore controls + action: { click: { css: '[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] a:has-text("Manage")', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.lifecycle"][data-knowledge-status="archived"] button:has-text("Prepare restore for review")', internal: true }] } + - id: prepare-book-restore + title: Create the book restore draft + action: { click: { css: '[data-scene="knowledge.lifecycle.form"] button:has-text("Prepare restore for review")', internal: true } } + expect: { urlIncludes: workspace= } + - id: submit-book-restore + title: Submit the restored book for independent review + action: { click: { role: button, name: Submit for review } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: await-book-restore-review-navigation + title: Wait for the restored book review queue to finish loading + action: { pause: { mode: timed, durationSeconds: 10 } } + expect: { urlIncludes: view=reviews } + - id: sign-out-book-restore-author + title: End the book restore author's session + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in } + - id: enter-book-restore-reviewer + title: Enter the independent restore reviewer + action: { fill: { role: textbox, name: Email or username, value: visual.knowledge-reviewer@treeseed.io } } + expect: { text: Sign in } + - id: password-book-restore-reviewer + title: Enter the restore reviewer password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: authenticate-book-restore-reviewer + title: Authenticate the book restore reviewer + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app } + - id: approve-book-restore + title: Open and approve the exact book restore review + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] [data-scene="knowledge.review.decision"]', internal: true }] } + - id: decide-book-restore + title: Approve the book restore independently + action: { click: { css: '[data-review-status="open"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] button[value="approve"]', internal: true } } + expect: { text: Review decision recorded. } + - id: reload-book-restore + title: Reload the durable book restore approval + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="approved"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] [data-scene="knowledge.review.publish"]', internal: true }] } + - id: publish-book-restore + title: Publish the approved book restoration + action: { click: { css: '[data-review-status="approved"][data-review-paths*="books/guarantee-book-{{runShort}}-{{deviceId}}.md"] [data-scene="knowledge.review.publish"] button', internal: true } } + expect: { text: Approved knowledge publication queued. } + - id: await-book-restore + title: Wait for atomic restored-book publication + action: { waitForOperation: { kind: "knowledge:publish_review", source: linked, status: [succeeded], timeoutSeconds: 180, pollIntervalSeconds: 2 } } + expect: { urlIncludes: /app/knowledge } + - id: sign-out-book-restore-reviewer + title: End the reviewer session before restoring the page + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in } + - id: enter-page-restore-author + title: Return to the authorized page restore author + action: { fill: { role: textbox, name: Email or username, value: visual.platform-admin@treeseed.io } } + expect: { text: Sign in } + - id: password-page-restore-author + title: Enter the page restore author's password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: authenticate-page-restore-author + title: Authenticate the page restore author + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app } + - id: reopen-restored-book-outline + title: Open the restored book outline containing the archived page + action: { goto: /app/knowledge } + expect: { visible: [{ css: 'details[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] summary', internal: true }] } + - id: expand-restored-book-outline + title: Expand the restored book outline + action: { click: { css: 'details[data-book-id="guarantee-book-{{runShort}}-{{deviceId}}"] summary', internal: true } } + expect: { visible: [{ css: '[data-page-id="guarantee-page-{{runShort}}-{{deviceId}}"] a:has-text("Edit page")', internal: true }] } + - id: manage-archived-page + title: Open the archived page restore controls + action: { click: { css: '[data-page-id="guarantee-page-{{runShort}}-{{deviceId}}"] a:has-text("Edit page")', internal: true } } + expect: { visible: [{ css: '[data-scene="knowledge.lifecycle"][data-knowledge-kind="page"][data-knowledge-status="archived"]', internal: true }] } + - id: prepare-page-restore + title: Prepare the page restoration through the rendered control + action: { click: { css: '[data-scene="knowledge.lifecycle.form"] button:has-text("Prepare restore for review")', internal: true } } + expect: { urlIncludes: workspace=, visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: submit-page-restore + title: Submit the restored page for independent review + action: { click: { role: button, name: Submit for review } } + expect: { visible: [{ css: '[data-scene="knowledge.editor.form"]', internal: true }] } + - id: await-page-restore-review-navigation + title: Wait for the restored page review queue to finish loading + action: { pause: { mode: timed, durationSeconds: 10 } } + expect: { urlIncludes: view=reviews } + - id: sign-out-page-restore-author + title: End the page restore author's session + action: { clickVisibleSequence: [{ role: button, name: Open team operations }, { role: button, name: Sign out }] } + expect: { urlIncludes: /auth/sign-in } + - id: enter-page-restore-reviewer + title: Enter the independent page restore reviewer + action: { fill: { role: textbox, name: Email or username, value: visual.knowledge-reviewer@treeseed.io } } + expect: { text: Sign in } + - id: password-page-restore-reviewer + title: Enter the page restore reviewer password + action: { fill: { css: 'input[name="password"]', internal: true, value: "TreeSeedVisualAudit!2026" } } + expect: { text: Sign in } + - id: authenticate-page-restore-reviewer + title: Authenticate the page restore reviewer + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app } + - id: approve-page-restore + title: Open the exact page restore review + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] [data-scene="knowledge.review.decision"]', internal: true }] } + - id: decide-page-restore + title: Approve the page restoration independently + action: { click: { css: '[data-review-status="open"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] button[value="approve"]', internal: true } } + expect: { text: Review decision recorded. } + - id: reload-page-restore + title: Reload the durable page restore approval + action: { goto: /app/knowledge?view=reviews } + expect: { visible: [{ css: '[data-review-status="approved"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] [data-scene="knowledge.review.publish"]', internal: true }] } + - id: publish-page-restore + title: Publish the approved page restoration + action: { click: { css: '[data-review-status="approved"][data-review-paths*="guarantee-book-{{runShort}}-{{deviceId}}/getting-started.md"] [data-scene="knowledge.review.publish"] button', internal: true } } + expect: { text: Approved knowledge publication queued. } + - id: await-page-restore + title: Wait for atomic restored-page publication + action: { waitForOperation: { kind: "knowledge:publish_review", source: linked, status: [succeeded], timeoutSeconds: 180, pollIntervalSeconds: 2 } } + expect: { urlIncludes: /app/knowledge } + - id: verify-restored-page + title: Prove the restored page is served from the final atomic revision + action: { goto: "/t/treeseed/books/guarantee-book-{{runShort}}-{{deviceId}}/getting-started" } + expect: { text: This page is published from an exact TreeDX commit., urlIncludes: /getting-started } +chapters: + - { id: workspace, title: Create an isolated authoring workspace, startsAt: open-workbench } + - { id: book, title: Validate and author a repository-native book, startsAt: reject-empty-book } + - { id: page, title: Author safe book knowledge, startsAt: choose-page } + - { id: review, title: Enforce independent review and atomic publication, startsAt: submit-knowledge-review } + - { id: reader, title: Search and render the exact published revision, startsAt: search-library } + - { id: pack, title: Build immutable single-book and selected-book packs, startsAt: return-to-packs } + - { id: lifecycle, title: Resolve dependencies and archive and restore knowledge, startsAt: open-book-lifecycle-blockers } +runtime: { mode: training, timeouts: { sceneSeconds: 1800, chapterSeconds: 900, stepSeconds: 90 }, checkpoints: { enabled: true, defaultResumable: false, everyStep: true }, progress: { heartbeatSeconds: 15 }, failure: { continueOnFailure: false } } +visualAudit: { enabled: true } diff --git a/guarantees/project/book/scenes/create-book.scene.yaml b/guarantees/project/book/scenes/create-book.scene.yaml deleted file mode 100644 index 3af04e8f..00000000 --- a/guarantees/project/book/scenes/create-book.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.book.create-book.065 -title: Create Book -description: Scene scaffold for guarantee.project.book.create-book.065. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Book opens the canonical @treeseed/admin full page form workflow. - - Create Book exercises a service journey instead of only loading /app/knowledge/books. - - Create Book records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Book - action: - goto: /app/knowledge/books - expect: - urlIncludes: /app/knowledge - - id: inspect-service-surface - title: Inspect Create Book service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/knowledge -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/book/scenes/delete-book.scene.yaml b/guarantees/project/book/scenes/delete-book.scene.yaml deleted file mode 100644 index 7cbe370c..00000000 --- a/guarantees/project/book/scenes/delete-book.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.book.delete-book.067 -title: Delete Book -description: Scene scaffold for guarantee.project.book.delete-book.067. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Book opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Book exercises a service journey instead of only loading /app/knowledge/books/seed-book. - - Delete Book records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Book - action: - goto: /app/knowledge/books/seed-book - expect: - urlIncludes: /app/knowledge - - id: inspect-service-surface - title: Inspect Delete Book service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/knowledge -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/book/scenes/download-book.scene.yaml b/guarantees/project/book/scenes/download-book.scene.yaml deleted file mode 100644 index f610cb5b..00000000 --- a/guarantees/project/book/scenes/download-book.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.book.download-book.070 -title: Download Book -description: Scene scaffold for guarantee.project.book.download-book.070. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Download Book opens the canonical @treeseed/admin record action workflow. - - Download Book exercises a service journey instead of only loading /app/knowledge/books/seed-book. - - Download Book records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Download Book - action: - goto: /app/knowledge/books/seed-book - expect: - urlIncludes: /app/knowledge - - id: inspect-service-surface - title: Inspect Download Book service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/knowledge -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/book/scenes/edit-book.scene.yaml b/guarantees/project/book/scenes/edit-book.scene.yaml deleted file mode 100644 index b1f03b4b..00000000 --- a/guarantees/project/book/scenes/edit-book.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.book.edit-book.066 -title: Edit Book -description: Scene scaffold for guarantee.project.book.edit-book.066. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Book opens the canonical @treeseed/admin full page form workflow. - - Edit Book exercises a service journey instead of only loading /app/knowledge/books/seed-book. - - Edit Book records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Book - action: - goto: /app/knowledge/books/seed-book - expect: - urlIncludes: /app/knowledge - - id: inspect-service-surface - title: Inspect Edit Book service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/knowledge -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/book/scenes/negative/anonymous-knowledge-access.scene.yaml b/guarantees/project/book/scenes/negative/anonymous-knowledge-access.scene.yaml new file mode 100644 index 00000000..7d85542a --- /dev/null +++ b/guarantees/project/book/scenes/negative/anonymous-knowledge-access.scene.yaml @@ -0,0 +1,58 @@ +schemaVersion: treeseed.scene/v1 +id: knowledge.negative.anonymous-access +title: Anonymous Knowledge Administration Denial +description: Anonymous visitors remain at the authentication boundary and cannot render knowledge mutation controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [knowledge.book-authoring, knowledge.book-lifecycle, knowledge.page-authoring, knowledge.page-lifecycle, knowledge.relationships, knowledge.review-publication, knowledge.packs] + minimumSteps: 3 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: anonymous, required: false } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: deny-workbench + title: Redirect anonymous workbench access + action: { goto: /app/knowledge } + expect: + urlIncludes: "/auth/sign-in?returnTo=" + text: Sign in + notVisible: [{ role: button, name: Create draft workspace }] + - id: exercise-authentication-boundary + title: Exercise the visible sign-in boundary without authenticating + action: + fill: { role: textbox, name: Email or username, value: anonymous-knowledge-boundary } + expect: + urlIncludes: "/auth/sign-in?returnTo=" + visible: [{ role: button, name: Sign in }] + - id: deny-project-books + title: Redirect project book administration access + action: { goto: /app/projects/inaccessible-project/books } + expect: + urlIncludes: "/auth/sign-in?returnTo=" + notVisible: [{ role: button, name: Create draft workspace }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/project/book/scenes/negative/contributor-knowledge-lifecycle.scene.yaml b/guarantees/project/book/scenes/negative/contributor-knowledge-lifecycle.scene.yaml new file mode 100644 index 00000000..1b38b218 --- /dev/null +++ b/guarantees/project/book/scenes/negative/contributor-knowledge-lifecycle.scene.yaml @@ -0,0 +1,64 @@ +schemaVersion: treeseed.scene/v1 +id: knowledge.negative.contributor-lifecycle +title: Contributor Knowledge Lifecycle Denial +description: A contributor can author knowledge but cannot render review, publication, lifecycle, or pack administration controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [knowledge.book-lifecycle, knowledge.page-lifecycle, knowledge.review-publication, knowledge.packs] + minimumSteps: 4 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: member, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-team-collection + title: Open the contributor team collection + action: { goto: /app/teams } + expect: { visible: [{ css: ':nth-match([data-scene="team.active.set"], 1)', internal: true }] } + - id: select-team-context + title: Select the contributor team + action: { click: { css: ':nth-match([data-scene="team.active.set"] button, 1)', internal: true } } + expect: { visible: [{ css: '[data-active="true"]', internal: true }] } + - id: inspect-authoring-boundary + title: Retain authoring while omitting elevated controls + action: { goto: /app/knowledge } + expect: + visible: [{ css: '.ts-surface-tab[href*="view=author"]', internal: true }] + notVisible: + - { css: '.ts-surface-tab[href*="view=reviews"]', internal: true } + - { css: '.ts-surface-tab[href*="view=packs"]', internal: true } + - { role: button, name: Archive } + - { role: button, name: Restore } + - id: deny-direct-review-view + title: Fail closed on a direct review URL + action: { goto: "/app/knowledge?view=reviews" } + expect: + text: Knowledge controls unavailable + notVisible: + - { role: button, name: Approve } + - { role: button, name: Publish } +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 240, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/project/book/scenes/negative/nonmember-knowledge-access.scene.yaml b/guarantees/project/book/scenes/negative/nonmember-knowledge-access.scene.yaml new file mode 100644 index 00000000..30d4bbca --- /dev/null +++ b/guarantees/project/book/scenes/negative/nonmember-knowledge-access.scene.yaml @@ -0,0 +1,61 @@ +schemaVersion: treeseed.scene/v1 +id: knowledge.negative.nonmember-access +title: Nonmember Knowledge Isolation +description: An authenticated nonmember cannot select another team's knowledge or render authoring controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [knowledge.library, knowledge.book-authoring, knowledge.book-lifecycle, knowledge.page-authoring, knowledge.page-lifecycle, knowledge.relationships, knowledge.review-publication, knowledge.packs, knowledge.reader] + minimumSteps: 3 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: nonmember, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: isolate-workbench + title: Require an accessible active team + action: { goto: /app/knowledge } + expect: + urlIncludes: /app/knowledge + text: Choose an active team + notVisible: + - { role: link, name: Author } + - { role: link, name: Reviews } + - { role: link, name: Packs } + - { role: button, name: Create draft workspace } + - id: deny-authoring-view + title: Keep the authoring view outside another team + action: { goto: "/app/knowledge?view=author" } + expect: + text: Choose an active team + notVisible: [{ role: button, name: Continue }] + - id: exercise-team-boundary + title: Open the team collection without another team's records + action: { click: { css: '#main-content a[href="/app/teams"]', internal: true } } + expect: + urlIncludes: /app/teams + text: No teams yet +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/project/book/scenes/negative/readonly-knowledge-controls.scene.yaml b/guarantees/project/book/scenes/negative/readonly-knowledge-controls.scene.yaml new file mode 100644 index 00000000..de800498 --- /dev/null +++ b/guarantees/project/book/scenes/negative/readonly-knowledge-controls.scene.yaml @@ -0,0 +1,63 @@ +schemaVersion: treeseed.scene/v1 +id: knowledge.negative.readonly-controls +title: Read-only Knowledge Mutation Denial +description: A read-only team member can inspect accessible knowledge but cannot render authoring, lifecycle, or pack controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [knowledge.library, knowledge.book-authoring, knowledge.book-lifecycle, knowledge.page-authoring, knowledge.page-lifecycle, knowledge.relationships, knowledge.packs, knowledge.reader] + minimumSteps: 4 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: viewer, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-team-collection + title: Open the accessible team collection + action: { goto: /app/teams } + expect: { visible: [{ css: ':nth-match([data-scene="team.active.set"], 1)', internal: true }] } + - id: select-team-context + title: Select the team through the visible preference control + action: { click: { css: ':nth-match([data-scene="team.active.set"] button, 1)', internal: true } } + expect: { visible: [{ css: '[data-active="true"]', internal: true }] } + - id: inspect-readable-library + title: Read knowledge without authoring controls + action: { goto: /app/knowledge } + expect: + visible: [{ css: '.ts-surface-tab[href="/app/knowledge"]', internal: true }] + notVisible: + - { css: '.ts-surface-tab[href*="view=author"]', internal: true } + - { css: '.ts-surface-tab[href*="view=packs"]', internal: true } + - { role: button, name: Create draft workspace } + - { role: button, name: Archive } + - { role: button, name: Restore } + - id: deny-direct-authoring-view + title: Fail closed on a direct authoring URL + action: { goto: "/app/knowledge?view=author" } + expect: + text: Knowledge controls unavailable + notVisible: [{ role: button, name: Continue }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 240, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/project/book/scenes/search-books.scene.yaml b/guarantees/project/book/scenes/search-books.scene.yaml deleted file mode 100644 index aa7402b1..00000000 --- a/guarantees/project/book/scenes/search-books.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.book.search-books.068 -title: Search Books -description: Scene scaffold for guarantee.project.book.search-books.068. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Search Books opens the canonical @treeseed/admin dashboard read model workflow. - - Search Books exercises a service journey instead of only loading /app/knowledge/books. - - Search Books records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Search Books - action: - goto: /app/knowledge/books - expect: - urlIncludes: /app/knowledge - - id: inspect-service-surface - title: Inspect Search Books service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/knowledge -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/book/search-books.guarantee.yaml b/guarantees/project/book/search-books.guarantee.yaml index 1d9efda4..22ebd12b 100644 --- a/guarantees/project/book/search-books.guarantee.yaml +++ b/guarantees/project/book/search-books.guarantee.yaml @@ -5,69 +5,21 @@ type: project subtype: book journey: Search Books ownerPackage: "@treeseed/admin" -summary: Search project books and metadata through content indexes; should not scan local fixture files in production workflows. +surface: admin-ui +summary: Search the authorized federated book library through TreeDX without filesystem scanning or metadata leakage. status: active -dependencies: - journeys: - - 65 - guarantees: - - guarantee.project.book.create-book.065 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 65" -scene: - required: true - manifest: ./scenes/search-books.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/knowledge/books - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.book.search-books.api -content: - required: true - verifierRefs: - - admin.project.book.search-books.content -audit: - required: true - verifierRefs: - - admin.project.book.search-books.audit +dependencies: { journeys: [65], guarantees: [guarantee.project.book.create-book.065] } +actors: { allowed: [anonymous_user, authenticated_user, authorized_private_viewer], forbidden: [unauthorized_private_viewer] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.library, knowledge.reader] } +scene: { required: true, manifest: scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /books, componentContract: federated knowledge search } +api: { required: true, verifierRefs: [api.knowledge.contextual-policy] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content, core.knowledge.starlight-reader] } +audit: { required: false, verifierRefs: [] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.book.search-books.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Search project books and metadata through content indexes; should not scan local fixture files in production workflows. + - { id: private-library-isolation, actor: unauthorized_private_viewer, sceneManifest: scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.contextual-policy] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref] } +notes: [The shared execution searches the authorized federated runtime and opens the exact atomic Starlight revision.] +run: { requiredForRelease: true } diff --git a/guarantees/project/decision/create-note-on-decision.guarantee.yaml b/guarantees/project/decision/create-note-on-decision.guarantee.yaml deleted file mode 100644 index ef5cede4..00000000 --- a/guarantees/project/decision/create-note-on-decision.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.decision.create-note-on-decision.056 -journeyIndex: 56 -type: project -subtype: decision -journey: Create Note on Decision -ownerPackage: "@treeseed/admin" -summary: Attach notes to decisions using relatedDecisions or about frontmatter; should preserve why a decision was made. -status: active -dependencies: - journeys: - - 50 - guarantees: - - guarantee.project.proposal.vote-on-proposal.050 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 50" -scene: - required: true - manifest: ./scenes/create-note-on-decision.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/decisions/seed-decision - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.decision.create-note-on-decision.api -content: - required: true - verifierRefs: - - admin.project.decision.create-note-on-decision.content -audit: - required: true - verifierRefs: - - admin.project.decision.create-note-on-decision.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.decision.create-note-on-decision.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Attach notes to decisions using relatedDecisions or about frontmatter; should preserve why a decision was made. diff --git a/guarantees/project/decision/scenes/create-note-on-decision.scene.yaml b/guarantees/project/decision/scenes/create-note-on-decision.scene.yaml deleted file mode 100644 index 0307b378..00000000 --- a/guarantees/project/decision/scenes/create-note-on-decision.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.decision.create-note-on-decision.056 -title: Create Note on Decision -description: Scene scaffold for guarantee.project.decision.create-note-on-decision.056. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Note On Decision opens the canonical @treeseed/admin full page form workflow. - - Create Note On Decision exercises a service journey instead of only loading /app/work/decisions/seed-decision. - - Create Note On Decision records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Note on Decision - action: - goto: /app/work/decisions/seed-decision - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Create Note on Decision service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/decision/scenes/search-decisions.scene.yaml b/guarantees/project/decision/scenes/search-decisions.scene.yaml deleted file mode 100644 index de488f27..00000000 --- a/guarantees/project/decision/scenes/search-decisions.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.decision.search-decisions.055 -title: Search Decisions -description: Scene scaffold for guarantee.project.decision.search-decisions.055. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Search Decisions opens the canonical @treeseed/admin dashboard read model workflow. - - Search Decisions exercises a service journey instead of only loading /app/work/decisions. - - Search Decisions records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Search Decisions - action: - goto: /app/work/decisions - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Search Decisions service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/decision/search-decisions.guarantee.yaml b/guarantees/project/decision/search-decisions.guarantee.yaml deleted file mode 100644 index beac55dd..00000000 --- a/guarantees/project/decision/search-decisions.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.decision.search-decisions.055 -journeyIndex: 55 -type: project -subtype: decision -journey: Search Decisions -ownerPackage: "@treeseed/admin" -summary: Search accepted or rejected decisions created from proposal review; decisions gate acting mode and capacity-plan provenance. -status: active -dependencies: - journeys: - - 50 - guarantees: - - guarantee.project.proposal.vote-on-proposal.050 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 50" -scene: - required: true - manifest: ./scenes/search-decisions.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/decisions - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.decision.search-decisions.api -content: - required: true - verifierRefs: - - admin.project.decision.search-decisions.content -audit: - required: true - verifierRefs: - - admin.project.decision.search-decisions.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.decision.search-decisions.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Search accepted or rejected decisions created from proposal review; decisions gate acting mode and capacity-plan provenance. diff --git a/guarantees/project/knowledge/archive-book-page.guarantee.yaml b/guarantees/project/knowledge/archive-book-page.guarantee.yaml new file mode 100644 index 00000000..8d465f86 --- /dev/null +++ b/guarantees/project/knowledge/archive-book-page.guarantee.yaml @@ -0,0 +1,28 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.project.knowledge.delete-book-page.072 +journeyIndex: 72 +type: project +subtype: knowledge +journey: Archive And Restore Book Page +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Archive and restore a knowledge page after inspecting backlinks and affected packs. +status: active +dependencies: { journeys: [69], guarantees: [guarantee.project.knowledge.create-book-page.069] } +actors: { allowed: [project_manager], forbidden: [anonymous_user, non_member, project_viewer, project_contributor] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [security, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.page-lifecycle] } +scene: { required: true, manifest: ../book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: destructive backlink review } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.lifecycle.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content, core.knowledge.starlight-reader] } +audit: { required: true, verifierRefs: [api.knowledge.lifecycle.run-correlated] } +negativeCases: + - { id: anonymous-page-lifecycle-denied, actor: anonymous_user, sceneManifest: ../book/scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-page-lifecycle-denied, actor: non_member, sceneManifest: ../book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: readonly-page-lifecycle-denied, actor: project_viewer, sceneManifest: ../book/scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.control-plane] } + - { id: contributor-page-lifecycle-denied, actor: project_contributor, sceneManifest: ../book/scenes/negative/contributor-knowledge-lifecycle.scene.yaml, executionKey: admin.knowledge.negative.contributor, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } +notes: [The shared execution proves backlink and pack blockers followed by independently reviewed archive and restore publications.] +run: { requiredForRelease: true } diff --git a/guarantees/project/knowledge/create-book-page.guarantee.yaml b/guarantees/project/knowledge/create-book-page.guarantee.yaml index cc4f431d..82c73333 100644 --- a/guarantees/project/knowledge/create-book-page.guarantee.yaml +++ b/guarantees/project/knowledge/create-book-page.guarantee.yaml @@ -5,69 +5,23 @@ type: project subtype: knowledge journey: Create Book Page ownerPackage: "@treeseed/admin" -summary: Create a knowledge page inside a book with required frontmatter and links; agent artifacts must be real Knowledge Hub content. +surface: admin-ui +summary: Create a safe Markdown knowledge page with schema metadata and stable relationships through TreeDX. status: active -dependencies: - journeys: - - 65 - guarantees: - - guarantee.project.book.create-book.065 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 65" -scene: - required: true - manifest: ./scenes/create-book-page.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/knowledge - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.knowledge.create-book-page.api -content: - required: true - verifierRefs: - - admin.project.knowledge.create-book-page.content -audit: - required: true - verifierRefs: - - admin.project.knowledge.create-book-page.audit +dependencies: { journeys: [65], guarantees: [guarantee.project.book.create-book.065] } +actors: { allowed: [project_contributor, project_manager], forbidden: [anonymous_user, non_member, project_viewer] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.page-authoring, knowledge.relationships, knowledge.review-publication] } +scene: { required: true, manifest: ../book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: rich knowledge editor } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content] } +audit: { required: true, verifierRefs: [api.knowledge.run-correlated] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.knowledge.create-book-page.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create a knowledge page inside a book with required frontmatter and links; agent artifacts must be real Knowledge Hub content. + - { id: anonymous-page-authoring-denied, actor: anonymous_user, sceneManifest: ../book/scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-page-authoring-denied, actor: non_member, sceneManifest: ../book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: readonly-page-authoring-denied, actor: project_viewer, sceneManifest: ../book/scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } +notes: [The shared execution creates safe Markdown and real note and question relationships through rendered controls.] +run: { requiredForRelease: true } diff --git a/guarantees/project/knowledge/delete-book-page.guarantee.yaml b/guarantees/project/knowledge/delete-book-page.guarantee.yaml deleted file mode 100644 index 90208a59..00000000 --- a/guarantees/project/knowledge/delete-book-page.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.knowledge.delete-book-page.072 -journeyIndex: 72 -type: project -subtype: knowledge -journey: Delete Book Page -ownerPackage: "@treeseed/admin" -summary: Delete or archive a page with backlinks and book index updates; direct filesystem deletion is not appropriate. -status: active -dependencies: - journeys: - - 69 - guarantees: - - guarantee.project.knowledge.create-book-page.069 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 69" -scene: - required: true - manifest: ./scenes/delete-book-page.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/knowledge/seed-page - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.knowledge.delete-book-page.api -content: - required: true - verifierRefs: - - admin.project.knowledge.delete-book-page.content -audit: - required: true - verifierRefs: - - admin.project.knowledge.delete-book-page.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.knowledge.delete-book-page.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Delete or archive a page with backlinks and book index updates; direct filesystem deletion is not appropriate. diff --git a/guarantees/project/knowledge/edit-book-page.guarantee.yaml b/guarantees/project/knowledge/edit-book-page.guarantee.yaml index 9d556ff6..c11e0b91 100644 --- a/guarantees/project/knowledge/edit-book-page.guarantee.yaml +++ b/guarantees/project/knowledge/edit-book-page.guarantee.yaml @@ -5,69 +5,23 @@ type: project subtype: knowledge journey: Edit Book Page ownerPackage: "@treeseed/admin" -summary: Edit page content through TreeDX with validation and provenance; should preserve links to questions objectives proposals or decisions. +surface: admin-ui +summary: Edit page Markdown and metadata without losing relationships or overwriting a newer source revision. status: active -dependencies: - journeys: - - 69 - guarantees: - - guarantee.project.knowledge.create-book-page.069 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 69" -scene: - required: true - manifest: ./scenes/edit-book-page.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/knowledge/seed-page - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.knowledge.edit-book-page.api -content: - required: true - verifierRefs: - - admin.project.knowledge.edit-book-page.content -audit: - required: true - verifierRefs: - - admin.project.knowledge.edit-book-page.audit +dependencies: { journeys: [69], guarantees: [guarantee.project.knowledge.create-book-page.069] } +actors: { allowed: [project_contributor, project_manager], forbidden: [anonymous_user, non_member, project_viewer] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.page-authoring] } +scene: { required: true, manifest: ../book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: conflict-safe rich knowledge editor } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content] } +audit: { required: true, verifierRefs: [api.knowledge.run-correlated] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.knowledge.edit-book-page.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Edit page content through TreeDX with validation and provenance; should preserve links to questions objectives proposals or decisions. + - { id: anonymous-page-edit-denied, actor: anonymous_user, sceneManifest: ../book/scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-page-edit-denied, actor: non_member, sceneManifest: ../book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: readonly-page-edit-denied, actor: project_viewer, sceneManifest: ../book/scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } +notes: [The shared execution proves revision, review, exact commit publication, and persisted relationships.] +run: { requiredForRelease: true } diff --git a/guarantees/project/knowledge/review-backlinks.guarantee.yaml b/guarantees/project/knowledge/review-backlinks.guarantee.yaml index 30fc7b67..0d3f7ea9 100644 --- a/guarantees/project/knowledge/review-backlinks.guarantee.yaml +++ b/guarantees/project/knowledge/review-backlinks.guarantee.yaml @@ -5,79 +5,21 @@ type: project subtype: knowledge journey: Review Backlinks ownerPackage: "@treeseed/admin" -summary: Inspect relationships among questions objectives proposals decisions notes books and pages before delete/archive operations. +surface: admin-ui +summary: Inspect authorized TreeDX relationships and backlinks across knowledge and functional content before lifecycle changes. status: active -dependencies: - journeys: - - 38 - - 43 - - 48 - - 50 - - 65 - - 69 - guarantees: - - guarantee.project.question.ask-question.038 - - guarantee.project.objective.create-objective.043 - - guarantee.project.proposal.create-proposal.048 - - guarantee.project.proposal.vote-on-proposal.050 - - guarantee.project.book.create-book.065 - - guarantee.project.knowledge.create-book-page.069 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 38, 43, 48, 50, 65, 69" -scene: - required: true - manifest: ./scenes/review-backlinks.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/knowledge/seed-page - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.knowledge.review-backlinks.api -content: - required: true - verifierRefs: - - admin.project.knowledge.review-backlinks.content -audit: - required: true - verifierRefs: - - admin.project.knowledge.review-backlinks.audit +dependencies: { journeys: [65, 69], guarantees: [guarantee.project.book.create-book.065, guarantee.project.knowledge.create-book-page.069] } +actors: { allowed: [project_contributor, project_manager], forbidden: [unauthorized_project_viewer] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.relationships, knowledge.reader] } +scene: { required: true, manifest: ../book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: knowledge relationship inspector } +api: { required: true, verifierRefs: [api.knowledge.contextual-policy, api.knowledge.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.safe-content, core.knowledge.starlight-reader] } +audit: { required: false, verifierRefs: [] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.knowledge.review-backlinks.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Inspect relationships among questions objectives proposals decisions notes books and pages before delete/archive operations. + - { id: private-backlink-isolation, actor: unauthorized_project_viewer, sceneManifest: ../book/scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.contextual-policy] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref] } +notes: [The shared execution proves real TreeDX note and question lookup, persisted relationships, lifecycle dependency inspection, and authorized contextual resolution.] +run: { requiredForRelease: true } diff --git a/guarantees/project/knowledge/scenes/create-book-page.scene.yaml b/guarantees/project/knowledge/scenes/create-book-page.scene.yaml deleted file mode 100644 index 0ae18b31..00000000 --- a/guarantees/project/knowledge/scenes/create-book-page.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.knowledge.create-book-page.069 -title: Create Book Page -description: Scene scaffold for guarantee.project.knowledge.create-book-page.069. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Book Page opens the canonical @treeseed/admin full page form workflow. - - Create Book Page exercises a service journey instead of only loading /app/projects/project-visual-audit-project/knowledge. - - Create Book Page records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Book Page - action: - goto: /app/projects/project-visual-audit-project/knowledge - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Create Book Page service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/knowledge/scenes/delete-book-page.scene.yaml b/guarantees/project/knowledge/scenes/delete-book-page.scene.yaml deleted file mode 100644 index 86a4053f..00000000 --- a/guarantees/project/knowledge/scenes/delete-book-page.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.knowledge.delete-book-page.072 -title: Delete Book Page -description: Scene scaffold for guarantee.project.knowledge.delete-book-page.072. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Book Page opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Book Page exercises a service journey instead of only loading /app/projects/project-visual-audit-project/knowledge/seed-page. - - Delete Book Page records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Book Page - action: - goto: /app/projects/project-visual-audit-project/knowledge/seed-page - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Delete Book Page service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/knowledge/scenes/edit-book-page.scene.yaml b/guarantees/project/knowledge/scenes/edit-book-page.scene.yaml deleted file mode 100644 index 8ac14006..00000000 --- a/guarantees/project/knowledge/scenes/edit-book-page.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.knowledge.edit-book-page.071 -title: Edit Book Page -description: Scene scaffold for guarantee.project.knowledge.edit-book-page.071. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Book Page opens the canonical @treeseed/admin full page form workflow. - - Edit Book Page exercises a service journey instead of only loading /app/projects/project-visual-audit-project/knowledge/seed-page. - - Edit Book Page records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Book Page - action: - goto: /app/projects/project-visual-audit-project/knowledge/seed-page - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Edit Book Page service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/knowledge/scenes/review-backlinks.scene.yaml b/guarantees/project/knowledge/scenes/review-backlinks.scene.yaml deleted file mode 100644 index 2f13dae6..00000000 --- a/guarantees/project/knowledge/scenes/review-backlinks.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.knowledge.review-backlinks.091 -title: Review Backlinks -description: Scene scaffold for guarantee.project.knowledge.review-backlinks.091. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Review Backlinks opens the canonical @treeseed/admin dashboard read model workflow. - - Review Backlinks exercises a service journey instead of only loading /app/projects/project-visual-audit-project/knowledge/seed-page. - - Review Backlinks records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Review Backlinks - action: - goto: /app/projects/project-visual-audit-project/knowledge/seed-page - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Review Backlinks service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/library/download-book.guarantee.yaml b/guarantees/project/library/download-book.guarantee.yaml new file mode 100644 index 00000000..9bc679a5 --- /dev/null +++ b/guarantees/project/library/download-book.guarantee.yaml @@ -0,0 +1,27 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.project.book.download-book.070 +journeyIndex: 70 +type: project +subtype: library +journey: Build Book Knowledge Pack +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Build and download an immutable one-book pack from an exact authorized TreeDX source closure. +status: active +dependencies: { journeys: [65, 69], guarantees: [guarantee.project.book.create-book.065, guarantee.project.knowledge.create-book-page.069] } +actors: { allowed: [project_contributor, project_manager], forbidden: [anonymous_user, non_member, unauthorized_project_viewer] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.packs] } +scene: { required: true, manifest: ../book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: knowledge pack builder } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.pack.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.pack-integrity] } +audit: { required: true, verifierRefs: [api.knowledge.pack.run-correlated] } +negativeCases: + - { id: anonymous-pack-denied, actor: anonymous_user, sceneManifest: ../book/scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-pack-denied, actor: non_member, sceneManifest: ../book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: private-pack-isolation, actor: unauthorized_project_viewer, sceneManifest: ../book/scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.contextual-policy] } +evidence: { required: [playwright_trace, api_verification_log, knowledge_pack_artifact, audit_event_id] } +notes: [The shared execution builds and downloads the exact single-book artifact; the correlated verifier inspects its immutable bytes and source closure.] +run: { requiredForRelease: true } diff --git a/guarantees/project/library/download-library.guarantee.yaml b/guarantees/project/library/download-library.guarantee.yaml index f81e9aef..aba07fe4 100644 --- a/guarantees/project/library/download-library.guarantee.yaml +++ b/guarantees/project/library/download-library.guarantee.yaml @@ -3,71 +3,25 @@ id: guarantee.project.library.download-library.073 journeyIndex: 73 type: project subtype: library -journey: Download Library +journey: Build Selected Book Collection Pack ownerPackage: "@treeseed/admin" -summary: Export the project knowledge library from TreeDX-backed content; should honor project authorization and may need dependencies on books pages and library indexing. +surface: admin-ui +summary: Build a pack containing exactly a selected saved or ad hoc set of authorized books. status: active -dependencies: - journeys: - - 69 - guarantees: - - guarantee.project.knowledge.create-book-page.069 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 69" -scene: - required: true - manifest: ./scenes/download-library.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/knowledge - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.library.download-library.api -content: - required: true - verifierRefs: - - admin.project.library.download-library.content -audit: - required: true - verifierRefs: - - admin.project.library.download-library.audit +dependencies: { journeys: [65, 69], guarantees: [guarantee.project.book.create-book.065, guarantee.project.knowledge.create-book-page.069] } +actors: { allowed: [project_contributor, project_manager], forbidden: [anonymous_user, non_member, unauthorized_project_viewer] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.packs] } +scene: { required: true, manifest: ../book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: book collection pack builder } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.collection.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.pack-integrity] } +audit: { required: true, verifierRefs: [api.knowledge.collection.run-correlated] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.library.download-library.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Export the project knowledge library from TreeDX-backed content; should honor project authorization and may need dependencies on books pages and library indexing. + - { id: anonymous-collection-pack-denied, actor: anonymous_user, sceneManifest: ../book/scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-collection-pack-denied, actor: non_member, sceneManifest: ../book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: private-collection-pack-isolation, actor: unauthorized_project_viewer, sceneManifest: ../book/scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.contextual-policy] } +evidence: { required: [playwright_trace, api_verification_log, knowledge_pack_artifact, audit_event_id] } +notes: [The shared execution creates a saved two-book collection and the correlated verifier proves exact selected scope.] +run: { requiredForRelease: true } diff --git a/guarantees/project/library/rebuild-library-index.guarantee.yaml b/guarantees/project/library/rebuild-library-index.guarantee.yaml index 14df61d3..72bc67f7 100644 --- a/guarantees/project/library/rebuild-library-index.guarantee.yaml +++ b/guarantees/project/library/rebuild-library-index.guarantee.yaml @@ -5,71 +5,24 @@ type: project subtype: library journey: Rebuild Library Index ownerPackage: "@treeseed/admin" -summary: Refresh searchable project content indexes after book page or note changes; supports search and export journeys without filesystem scans. +surface: admin-ui +summary: Refresh the TreeDX graph and search index for the exact published content commit. status: active -dependencies: - journeys: - - 65 - - 69 - guarantees: - - guarantee.project.book.create-book.065 - - guarantee.project.knowledge.create-book-page.069 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 65, 69" -scene: - required: true - manifest: ./scenes/rebuild-library-index.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/knowledge - componentContract: record-action service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.library.rebuild-library-index.api -content: - required: true - verifierRefs: - - admin.project.library.rebuild-library-index.content -audit: - required: true - verifierRefs: - - admin.project.library.rebuild-library-index.audit +dependencies: { journeys: [65, 69], guarantees: [guarantee.project.book.create-book.065, guarantee.project.knowledge.create-book-page.069] } +actors: { allowed: [project_manager], forbidden: [anonymous_user, non_member, project_viewer, project_contributor] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [core, release] +preconditions: { fixtures: [integrated_treeseed_project] } +uiFeature: { contract: ../../admin/knowledge-authoring.ui-feature.yaml, capabilities: [knowledge.review-publication] } +scene: { required: true, manifest: ../book/scenes/author-publish-book.scene.yaml, executionKey: admin.knowledge.author-publish, entryRoute: /app/knowledge, componentContract: publication operation status } +api: { required: true, verifierRefs: [api.knowledge.control-plane, api.knowledge.run-correlated] } +content: { required: true, verifierRefs: [sdk.knowledge.content-sync] } +audit: { required: true, verifierRefs: [api.knowledge.run-correlated] } negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.library.rebuild-library-index.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Refresh searchable project content indexes after book page or note changes; supports search and export journeys without filesystem scans. + - { id: anonymous-publication-denied, actor: anonymous_user, sceneManifest: ../book/scenes/negative/anonymous-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.anonymous, verifierRefs: [api.knowledge.control-plane] } + - { id: nonmember-publication-denied, actor: non_member, sceneManifest: ../book/scenes/negative/nonmember-knowledge-access.scene.yaml, executionKey: admin.knowledge.negative.nonmember, verifierRefs: [api.knowledge.control-plane] } + - { id: readonly-publication-denied, actor: project_viewer, sceneManifest: ../book/scenes/negative/readonly-knowledge-controls.scene.yaml, executionKey: admin.knowledge.negative.readonly, verifierRefs: [api.knowledge.control-plane] } + - { id: author-publication-denied, actor: project_contributor, sceneManifest: ../book/scenes/negative/contributor-knowledge-lifecycle.scene.yaml, executionKey: admin.knowledge.negative.contributor, verifierRefs: [api.knowledge.control-plane] } +evidence: { required: [playwright_trace, api_verification_log, treedx_content_ref, audit_event_id] } +notes: [The shared publication operation requires exact Git commit and TreeDX graph parity before atomic promotion.] +run: { requiredForRelease: true } diff --git a/guarantees/project/library/scenes/download-library.scene.yaml b/guarantees/project/library/scenes/download-library.scene.yaml deleted file mode 100644 index 6a1eeedc..00000000 --- a/guarantees/project/library/scenes/download-library.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.library.download-library.073 -title: Download Library -description: Scene scaffold for guarantee.project.library.download-library.073. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Download Library opens the canonical @treeseed/admin record action workflow. - - Download Library exercises a service journey instead of only loading /app/knowledge. - - Download Library records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Download Library - action: - goto: /app/knowledge - expect: - urlIncludes: /app/knowledge - - id: inspect-service-surface - title: Inspect Download Library service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/knowledge -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/library/scenes/rebuild-library-index.scene.yaml b/guarantees/project/library/scenes/rebuild-library-index.scene.yaml deleted file mode 100644 index 23162165..00000000 --- a/guarantees/project/library/scenes/rebuild-library-index.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.library.rebuild-library-index.090 -title: Rebuild Library Index -description: Scene scaffold for guarantee.project.library.rebuild-library-index.090. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Rebuild Library Index opens the canonical @treeseed/admin dashboard read model workflow. - - Rebuild Library Index exercises a service journey instead of only loading /app/knowledge. - - Rebuild Library Index records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Rebuild Library Index - action: - goto: /app/knowledge - expect: - urlIncludes: /app/knowledge - - id: inspect-service-surface - title: Inspect Rebuild Library Index service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/knowledge -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/objective/create-note-on-objective.guarantee.yaml b/guarantees/project/objective/create-note-on-objective.guarantee.yaml deleted file mode 100644 index 2c6836a0..00000000 --- a/guarantees/project/objective/create-note-on-objective.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.objective.create-note-on-objective.047 -journeyIndex: 47 -type: project -subtype: objective -journey: Create Note on Objective -ownerPackage: "@treeseed/admin" -summary: Create a linked note with relatedObjectives or about frontmatter; this is a canonical planning artifact for workdays. -status: active -dependencies: - journeys: - - 43 - guarantees: - - guarantee.project.objective.create-objective.043 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 43" -scene: - required: true - manifest: ./scenes/create-note-on-objective.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/objectives/seed-objective - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.objective.create-note-on-objective.api -content: - required: true - verifierRefs: - - admin.project.objective.create-note-on-objective.content -audit: - required: true - verifierRefs: - - admin.project.objective.create-note-on-objective.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.objective.create-note-on-objective.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create a linked note with relatedObjectives or about frontmatter; this is a canonical planning artifact for workdays. diff --git a/guarantees/project/objective/create-objective.guarantee.yaml b/guarantees/project/objective/create-objective.guarantee.yaml deleted file mode 100644 index 2212d5e7..00000000 --- a/guarantees/project/objective/create-objective.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.objective.create-objective.043 -journeyIndex: 43 -type: project -subtype: objective -journey: Create Objective -ownerPackage: "@treeseed/admin" -summary: Create an objective in the project content model through TreeDX; objectives drive planning work and should be eligible for agent context. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/create-objective.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/objectives/new - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.objective.create-objective.api -content: - required: true - verifierRefs: - - admin.project.objective.create-objective.content -audit: - required: true - verifierRefs: - - admin.project.objective.create-objective.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.objective.create-objective.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create an objective in the project content model through TreeDX; objectives drive planning work and should be eligible for agent context. diff --git a/guarantees/project/objective/delete-objective.guarantee.yaml b/guarantees/project/objective/delete-objective.guarantee.yaml deleted file mode 100644 index 04d166f9..00000000 --- a/guarantees/project/objective/delete-objective.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.objective.delete-objective.045 -journeyIndex: 45 -type: project -subtype: objective -journey: Delete Objective -ownerPackage: "@treeseed/admin" -summary: Delete or archive an objective with dependency checks; should not leave orphaned proposals notes or decisions. -status: active -dependencies: - journeys: - - 43 - guarantees: - - guarantee.project.objective.create-objective.043 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 43" -scene: - required: true - manifest: ./scenes/delete-objective.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/objectives/seed-objective - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.objective.delete-objective.api -content: - required: true - verifierRefs: - - admin.project.objective.delete-objective.content -audit: - required: true - verifierRefs: - - admin.project.objective.delete-objective.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.objective.delete-objective.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Delete or archive an objective with dependency checks; should not leave orphaned proposals notes or decisions. diff --git a/guarantees/project/objective/edit-objective.guarantee.yaml b/guarantees/project/objective/edit-objective.guarantee.yaml deleted file mode 100644 index 578d50a2..00000000 --- a/guarantees/project/objective/edit-objective.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.objective.edit-objective.044 -journeyIndex: 44 -type: project -subtype: objective -journey: Edit Objective -ownerPackage: "@treeseed/admin" -summary: Edit objective fields and status while preserving links to proposals decisions notes and workday artifacts. -status: active -dependencies: - journeys: - - 43 - guarantees: - - guarantee.project.objective.create-objective.043 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 43" -scene: - required: true - manifest: ./scenes/edit-objective.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/objectives/seed-objective/edit - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.objective.edit-objective.api -content: - required: true - verifierRefs: - - admin.project.objective.edit-objective.content -audit: - required: true - verifierRefs: - - admin.project.objective.edit-objective.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.objective.edit-objective.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Edit objective fields and status while preserving links to proposals decisions notes and workday artifacts. diff --git a/guarantees/project/objective/scenes/create-note-on-objective.scene.yaml b/guarantees/project/objective/scenes/create-note-on-objective.scene.yaml deleted file mode 100644 index e5451a47..00000000 --- a/guarantees/project/objective/scenes/create-note-on-objective.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.objective.create-note-on-objective.047 -title: Create Note on Objective -description: Scene scaffold for guarantee.project.objective.create-note-on-objective.047. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Note On Objective opens the canonical @treeseed/admin full page form workflow. - - Create Note On Objective exercises a service journey instead of only loading /app/work/objectives/seed-objective. - - Create Note On Objective records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Note on Objective - action: - goto: /app/work/objectives/seed-objective - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Create Note on Objective service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/objective/scenes/create-objective.scene.yaml b/guarantees/project/objective/scenes/create-objective.scene.yaml deleted file mode 100644 index 48a6834d..00000000 --- a/guarantees/project/objective/scenes/create-objective.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.objective.create-objective.043 -title: Create Objective -description: Scene scaffold for guarantee.project.objective.create-objective.043. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Objective opens the canonical @treeseed/admin full page form workflow. - - Create Objective exercises a service journey instead of only loading /app/work/objectives/new. - - Create Objective records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Objective - action: - goto: /app/work/objectives/new - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Create Objective service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/objective/scenes/delete-objective.scene.yaml b/guarantees/project/objective/scenes/delete-objective.scene.yaml deleted file mode 100644 index e3292222..00000000 --- a/guarantees/project/objective/scenes/delete-objective.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.objective.delete-objective.045 -title: Delete Objective -description: Scene scaffold for guarantee.project.objective.delete-objective.045. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Objective opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Objective exercises a service journey instead of only loading /app/work/objectives/seed-objective. - - Delete Objective records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Objective - action: - goto: /app/work/objectives/seed-objective - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Delete Objective service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/objective/scenes/edit-objective.scene.yaml b/guarantees/project/objective/scenes/edit-objective.scene.yaml deleted file mode 100644 index 2bc060fd..00000000 --- a/guarantees/project/objective/scenes/edit-objective.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.objective.edit-objective.044 -title: Edit Objective -description: Scene scaffold for guarantee.project.objective.edit-objective.044. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Objective opens the canonical @treeseed/admin full page form workflow. - - Edit Objective exercises a service journey instead of only loading /app/work/objectives/seed-objective/edit. - - Edit Objective records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Objective - action: - goto: /app/work/objectives/seed-objective/edit - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Edit Objective service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/objective/scenes/search-objectives.scene.yaml b/guarantees/project/objective/scenes/search-objectives.scene.yaml deleted file mode 100644 index 1745e52d..00000000 --- a/guarantees/project/objective/scenes/search-objectives.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.objective.search-objectives.046 -title: Search Objectives -description: Scene scaffold for guarantee.project.objective.search-objectives.046. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Search Objectives opens the canonical @treeseed/admin dashboard read model workflow. - - Search Objectives exercises a service journey instead of only loading /app/work/objectives. - - Search Objectives records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Search Objectives - action: - goto: /app/work/objectives - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Search Objectives service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/objective/search-objectives.guarantee.yaml b/guarantees/project/objective/search-objectives.guarantee.yaml deleted file mode 100644 index bd5a9be0..00000000 --- a/guarantees/project/objective/search-objectives.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.objective.search-objectives.046 -journeyIndex: 46 -type: project -subtype: objective -journey: Search Objectives -ownerPackage: "@treeseed/admin" -summary: Search objectives by status ownership tags and related content; should use project-scoped content indexes rather than filesystem scans. -status: active -dependencies: - journeys: - - 43 - guarantees: - - guarantee.project.objective.create-objective.043 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 43" -scene: - required: true - manifest: ./scenes/search-objectives.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/objectives - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.objective.search-objectives.api -content: - required: true - verifierRefs: - - admin.project.objective.search-objectives.content -audit: - required: true - verifierRefs: - - admin.project.objective.search-objectives.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.objective.search-objectives.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Search objectives by status ownership tags and related content; should use project-scoped content indexes rather than filesystem scans. diff --git a/guarantees/project/project/create-project.guarantee.yaml b/guarantees/project/project/create-project.guarantee.yaml deleted file mode 100644 index e29dbc9c..00000000 --- a/guarantees/project/project/create-project.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.project.create-project.032 -journeyIndex: 32 -type: project -subtype: project -journey: Create Project -ownerPackage: "@treeseed/admin" -summary: Create a Treeseed project owned by a team with content model and TreeDX routing metadata; should not depend on local package checkout state. -status: active -dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 4" -scene: - required: true - manifest: ./scenes/create-project.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/new - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.project.create-project.api -content: - required: false - verifierRefs: - - admin.project.project.create-project.content -audit: - required: true - verifierRefs: - - admin.project.project.create-project.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.project.create-project.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create a Treeseed project owned by a team with content model and TreeDX routing metadata; should not depend on local package checkout state. diff --git a/guarantees/project/project/destroy-project.guarantee.yaml b/guarantees/project/project/destroy-project.guarantee.yaml deleted file mode 100644 index 122b175e..00000000 --- a/guarantees/project/project/destroy-project.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.project.destroy-project.036 -journeyIndex: 36 -type: project -subtype: project -journey: Destroy Project -ownerPackage: "@treeseed/admin" -summary: Destroy or archive a project with content retention provider assignment cleanup and TreeDX authorization cleanup; requires exact-state drift handling where infrastructure exists. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/destroy-project.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/delete - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.project.destroy-project.api -content: - required: false - verifierRefs: - - admin.project.project.destroy-project.content -audit: - required: true - verifierRefs: - - admin.project.project.destroy-project.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.project.destroy-project.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Destroy or archive a project with content retention provider assignment cleanup and TreeDX authorization cleanup; requires exact-state drift handling where infrastructure exists. diff --git a/guarantees/project/project/edit-project-settings.guarantee.yaml b/guarantees/project/project/edit-project-settings.guarantee.yaml deleted file mode 100644 index 92b6b512..00000000 --- a/guarantees/project/project/edit-project-settings.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.project.edit-project-settings.033 -journeyIndex: 33 -type: project -subtype: project -journey: Edit Project Settings -ownerPackage: "@treeseed/admin" -summary: Update project metadata agents and content settings through API models; project manifests may inform defaults but runtime edits need durable records. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/edit-project-settings.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/settings - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.project.edit-project-settings.api -content: - required: false - verifierRefs: - - admin.project.project.edit-project-settings.content -audit: - required: true - verifierRefs: - - admin.project.project.edit-project-settings.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.project.edit-project-settings.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Update project metadata agents and content settings through API models; project manifests may inform defaults but runtime edits need durable records. diff --git a/guarantees/project/project/monitor-project.guarantee.yaml b/guarantees/project/project/monitor-project.guarantee.yaml deleted file mode 100644 index 030d2c34..00000000 --- a/guarantees/project/project/monitor-project.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.project.monitor-project.035 -journeyIndex: 35 -type: project -subtype: project -journey: Monitor Project -ownerPackage: "@treeseed/admin" -summary: Show operational health for project workdays assignments content updates and hosted surfaces; needs trace links to API logs and TreeDX operations. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/monitor-project.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/seed-project - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.project.monitor-project.api -content: - required: false - verifierRefs: - - admin.project.project.monitor-project.content -audit: - required: true - verifierRefs: - - admin.project.project.monitor-project.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.project.monitor-project.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Show operational health for project workdays assignments content updates and hosted surfaces; needs trace links to API logs and TreeDX operations. diff --git a/guarantees/project/project/scenes/create-project.scene.yaml b/guarantees/project/project/scenes/create-project.scene.yaml deleted file mode 100644 index b0ecd1d0..00000000 --- a/guarantees/project/project/scenes/create-project.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.project.create-project.032 -title: Create Project -description: Scene scaffold for guarantee.project.project.create-project.032. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Project opens the canonical @treeseed/admin full page form workflow. - - Create Project exercises a service journey instead of only loading /app/projects/new. - - Create Project records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Project - action: - goto: /app/projects/new - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Create Project service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/project/scenes/destroy-project.scene.yaml b/guarantees/project/project/scenes/destroy-project.scene.yaml deleted file mode 100644 index e52c2426..00000000 --- a/guarantees/project/project/scenes/destroy-project.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.project.destroy-project.036 -title: Destroy Project -description: Scene scaffold for guarantee.project.project.destroy-project.036. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Destroy Project opens the canonical @treeseed/admin destructive confirmation workflow. - - Destroy Project exercises a service journey instead of only loading /app/projects/project-visual-audit-project/delete. - - Destroy Project records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Destroy Project - action: - goto: /app/projects/project-visual-audit-project/delete - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Destroy Project service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/project/scenes/edit-project-settings.scene.yaml b/guarantees/project/project/scenes/edit-project-settings.scene.yaml deleted file mode 100644 index 1bc7e5ac..00000000 --- a/guarantees/project/project/scenes/edit-project-settings.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.project.edit-project-settings.033 -title: Edit Project Settings -description: Scene scaffold for guarantee.project.project.edit-project-settings.033. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Project Settings opens the canonical @treeseed/admin full page form workflow. - - Edit Project Settings exercises a service journey instead of only loading /app/projects/project-visual-audit-project/settings. - - Edit Project Settings records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Project Settings - action: - goto: /app/projects/project-visual-audit-project/settings - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Edit Project Settings service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/project/scenes/monitor-project.scene.yaml b/guarantees/project/project/scenes/monitor-project.scene.yaml deleted file mode 100644 index fbc228bd..00000000 --- a/guarantees/project/project/scenes/monitor-project.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.project.monitor-project.035 -title: Monitor Project -description: Scene scaffold for guarantee.project.project.monitor-project.035. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Monitor Project opens the canonical @treeseed/admin record operations workflow. - - Monitor Project exercises a service journey instead of only loading /app/projects/seed-project. - - Monitor Project records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Monitor Project - action: - goto: /app/projects/seed-project - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Monitor Project service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/project/scenes/view-project-profile.scene.yaml b/guarantees/project/project/scenes/view-project-profile.scene.yaml deleted file mode 100644 index 3c77f4fb..00000000 --- a/guarantees/project/project/scenes/view-project-profile.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.project.view-project-profile.034 -title: View Project Profile -description: Scene scaffold for guarantee.project.project.view-project-profile.034. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - View Project Profile opens the canonical @treeseed/admin dashboard read model workflow. - - View Project Profile exercises a service journey instead of only loading /app/projects/seed-project. - - View Project Profile records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open View Project Profile - action: - goto: /app/projects/seed-project - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect View Project Profile service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/project/view-project-profile.guarantee.yaml b/guarantees/project/project/view-project-profile.guarantee.yaml deleted file mode 100644 index b46849e6..00000000 --- a/guarantees/project/project/view-project-profile.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.project.view-project-profile.034 -journeyIndex: 34 -type: project -subtype: project -journey: View Project Profile -ownerPackage: "@treeseed/admin" -summary: Present project overview including agents objectives decisions content and capacity posture; should aggregate API and TreeDX-backed content references. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/view-project-profile.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/seed-project - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.project.view-project-profile.api -content: - required: false - verifierRefs: - - admin.project.project.view-project-profile.content -audit: - required: true - verifierRefs: - - admin.project.project.view-project-profile.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.project.view-project-profile.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Present project overview including agents objectives decisions content and capacity posture; should aggregate API and TreeDX-backed content references. diff --git a/guarantees/project/proposal/create-note-on-proposal.guarantee.yaml b/guarantees/project/proposal/create-note-on-proposal.guarantee.yaml deleted file mode 100644 index ef377cf8..00000000 --- a/guarantees/project/proposal/create-note-on-proposal.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.proposal.create-note-on-proposal.054 -journeyIndex: 54 -type: project -subtype: proposal -journey: Create Note on Proposal -ownerPackage: "@treeseed/admin" -summary: Create linked proposal commentary with relatedProposals frontmatter; useful for reviews estimates and implementation notes. -status: active -dependencies: - journeys: - - 48 - guarantees: - - guarantee.project.proposal.create-proposal.048 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 48" -scene: - required: true - manifest: ./scenes/create-note-on-proposal.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/proposals/seed-proposal - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.proposal.create-note-on-proposal.api -content: - required: true - verifierRefs: - - admin.project.proposal.create-note-on-proposal.content -audit: - required: true - verifierRefs: - - admin.project.proposal.create-note-on-proposal.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.proposal.create-note-on-proposal.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create linked proposal commentary with relatedProposals frontmatter; useful for reviews estimates and implementation notes. diff --git a/guarantees/project/proposal/create-proposal.guarantee.yaml b/guarantees/project/proposal/create-proposal.guarantee.yaml deleted file mode 100644 index 3e3fdd8e..00000000 --- a/guarantees/project/proposal/create-proposal.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.proposal.create-proposal.048 -journeyIndex: 48 -type: project -subtype: proposal -journey: Create Proposal -ownerPackage: "@treeseed/admin" -summary: Create a project proposal tied to objectives or questions; proposals should be content model records and ready for review or voting. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/create-proposal.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/proposals/new - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.proposal.create-proposal.api -content: - required: true - verifierRefs: - - admin.project.proposal.create-proposal.content -audit: - required: true - verifierRefs: - - admin.project.proposal.create-proposal.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.proposal.create-proposal.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create a project proposal tied to objectives or questions; proposals should be content model records and ready for review or voting. diff --git a/guarantees/project/proposal/delete-proposal.guarantee.yaml b/guarantees/project/proposal/delete-proposal.guarantee.yaml deleted file mode 100644 index 7527161f..00000000 --- a/guarantees/project/proposal/delete-proposal.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.proposal.delete-proposal.051 -journeyIndex: 51 -type: project -subtype: proposal -journey: Delete Proposal -ownerPackage: "@treeseed/admin" -summary: Delete or archive proposals only after checking votes decisions and linked notes; destructive operations need audit trails. -status: active -dependencies: - journeys: - - 48 - guarantees: - - guarantee.project.proposal.create-proposal.048 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 48" -scene: - required: true - manifest: ./scenes/delete-proposal.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/proposals/seed-proposal - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.proposal.delete-proposal.api -content: - required: true - verifierRefs: - - admin.project.proposal.delete-proposal.content -audit: - required: true - verifierRefs: - - admin.project.proposal.delete-proposal.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.proposal.delete-proposal.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Delete or archive proposals only after checking votes decisions and linked notes; destructive operations need audit trails. diff --git a/guarantees/project/proposal/edit-proposal.guarantee.yaml b/guarantees/project/proposal/edit-proposal.guarantee.yaml deleted file mode 100644 index 0a575881..00000000 --- a/guarantees/project/proposal/edit-proposal.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.proposal.edit-proposal.049 -journeyIndex: 49 -type: project -subtype: proposal -journey: Edit Proposal -ownerPackage: "@treeseed/admin" -summary: Edit proposal content and readiness state with provenance; changes should remain visible to proposal inbox and workday planning. -status: active -dependencies: - journeys: - - 48 - guarantees: - - guarantee.project.proposal.create-proposal.048 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 48" -scene: - required: true - manifest: ./scenes/edit-proposal.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/proposals/seed-proposal/edit - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.proposal.edit-proposal.api -content: - required: true - verifierRefs: - - admin.project.proposal.edit-proposal.content -audit: - required: true - verifierRefs: - - admin.project.proposal.edit-proposal.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.proposal.edit-proposal.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Edit proposal content and readiness state with provenance; changes should remain visible to proposal inbox and workday planning. diff --git a/guarantees/project/proposal/proposal-inbox.guarantee.yaml b/guarantees/project/proposal/proposal-inbox.guarantee.yaml deleted file mode 100644 index 35187cde..00000000 --- a/guarantees/project/proposal/proposal-inbox.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.proposal.proposal-inbox.053 -journeyIndex: 53 -type: project -subtype: proposal -journey: Proposal Inbox -ownerPackage: "@treeseed/admin" -summary: Review pending proposals estimates and readiness signals; this surface is central for turning planning output into approved decisions. -status: active -dependencies: - journeys: - - 48 - guarantees: - - guarantee.project.proposal.create-proposal.048 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 48" -scene: - required: true - manifest: ./scenes/proposal-inbox.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/proposals - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.proposal.proposal-inbox.api -content: - required: true - verifierRefs: - - admin.project.proposal.proposal-inbox.content -audit: - required: true - verifierRefs: - - admin.project.proposal.proposal-inbox.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.proposal.proposal-inbox.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Review pending proposals estimates and readiness signals; this surface is central for turning planning output into approved decisions. diff --git a/guarantees/project/proposal/scenes/create-note-on-proposal.scene.yaml b/guarantees/project/proposal/scenes/create-note-on-proposal.scene.yaml deleted file mode 100644 index 052a0c2e..00000000 --- a/guarantees/project/proposal/scenes/create-note-on-proposal.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.proposal.create-note-on-proposal.054 -title: Create Note on Proposal -description: Scene scaffold for guarantee.project.proposal.create-note-on-proposal.054. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Note On Proposal opens the canonical @treeseed/admin full page form workflow. - - Create Note On Proposal exercises a service journey instead of only loading /app/work/proposals/seed-proposal. - - Create Note On Proposal records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Note on Proposal - action: - goto: /app/work/proposals/seed-proposal - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Create Note on Proposal service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/proposal/scenes/create-proposal.scene.yaml b/guarantees/project/proposal/scenes/create-proposal.scene.yaml deleted file mode 100644 index 1745adf6..00000000 --- a/guarantees/project/proposal/scenes/create-proposal.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.proposal.create-proposal.048 -title: Create Proposal -description: Scene scaffold for guarantee.project.proposal.create-proposal.048. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Create Proposal opens the canonical @treeseed/admin full page form workflow. - - Create Proposal exercises a service journey instead of only loading /app/work/proposals/new. - - Create Proposal records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Create Proposal - action: - goto: /app/work/proposals/new - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Create Proposal service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/proposal/scenes/delete-proposal.scene.yaml b/guarantees/project/proposal/scenes/delete-proposal.scene.yaml deleted file mode 100644 index d7637b9e..00000000 --- a/guarantees/project/proposal/scenes/delete-proposal.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.proposal.delete-proposal.051 -title: Delete Proposal -description: Scene scaffold for guarantee.project.proposal.delete-proposal.051. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Proposal opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Proposal exercises a service journey instead of only loading /app/work/proposals/seed-proposal. - - Delete Proposal records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Proposal - action: - goto: /app/work/proposals/seed-proposal - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Delete Proposal service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/proposal/scenes/edit-proposal.scene.yaml b/guarantees/project/proposal/scenes/edit-proposal.scene.yaml deleted file mode 100644 index 8feee39b..00000000 --- a/guarantees/project/proposal/scenes/edit-proposal.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.proposal.edit-proposal.049 -title: Edit Proposal -description: Scene scaffold for guarantee.project.proposal.edit-proposal.049. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Proposal opens the canonical @treeseed/admin full page form workflow. - - Edit Proposal exercises a service journey instead of only loading /app/work/proposals/seed-proposal/edit. - - Edit Proposal records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Proposal - action: - goto: /app/work/proposals/seed-proposal/edit - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Edit Proposal service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/proposal/scenes/proposal-inbox.scene.yaml b/guarantees/project/proposal/scenes/proposal-inbox.scene.yaml deleted file mode 100644 index 5cdc6b21..00000000 --- a/guarantees/project/proposal/scenes/proposal-inbox.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.proposal.proposal-inbox.053 -title: Proposal Inbox -description: Scene scaffold for guarantee.project.proposal.proposal-inbox.053. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Proposal Inbox opens the canonical @treeseed/admin dashboard read model workflow. - - Proposal Inbox exercises a service journey instead of only loading /app/work/proposals. - - Proposal Inbox records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Proposal Inbox - action: - goto: /app/work/proposals - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Proposal Inbox service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/proposal/scenes/search-proposals.scene.yaml b/guarantees/project/proposal/scenes/search-proposals.scene.yaml deleted file mode 100644 index 08b62f1a..00000000 --- a/guarantees/project/proposal/scenes/search-proposals.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.proposal.search-proposals.052 -title: Search Proposals -description: Scene scaffold for guarantee.project.proposal.search-proposals.052. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Search Proposals opens the canonical @treeseed/admin dashboard read model workflow. - - Search Proposals exercises a service journey instead of only loading /app/work/proposals. - - Search Proposals records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Search Proposals - action: - goto: /app/work/proposals - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Search Proposals service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/proposal/scenes/vote-on-proposal.scene.yaml b/guarantees/project/proposal/scenes/vote-on-proposal.scene.yaml deleted file mode 100644 index 807e77b5..00000000 --- a/guarantees/project/proposal/scenes/vote-on-proposal.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.proposal.vote-on-proposal.050 -title: Vote on Proposal -description: Scene scaffold for guarantee.project.proposal.vote-on-proposal.050. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Vote On Proposal opens the canonical @treeseed/admin record action workflow. - - Vote On Proposal exercises a service journey from the canonical proposal inbox. - - Vote On Proposal records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Vote on Proposal - action: - goto: /app/work/proposals - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect proposal voting service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/proposal/search-proposals.guarantee.yaml b/guarantees/project/proposal/search-proposals.guarantee.yaml deleted file mode 100644 index f4b02c96..00000000 --- a/guarantees/project/proposal/search-proposals.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.proposal.search-proposals.052 -journeyIndex: 52 -type: project -subtype: proposal -journey: Search Proposals -ownerPackage: "@treeseed/admin" -summary: Search proposals by state objective agent and decision status; should power planning dashboards and review workflows. -status: active -dependencies: - journeys: - - 48 - guarantees: - - guarantee.project.proposal.create-proposal.048 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 48" -scene: - required: true - manifest: ./scenes/search-proposals.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/proposals - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.proposal.search-proposals.api -content: - required: true - verifierRefs: - - admin.project.proposal.search-proposals.content -audit: - required: true - verifierRefs: - - admin.project.proposal.search-proposals.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.proposal.search-proposals.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Search proposals by state objective agent and decision status; should power planning dashboards and review workflows. diff --git a/guarantees/project/proposal/vote-on-proposal.guarantee.yaml b/guarantees/project/proposal/vote-on-proposal.guarantee.yaml deleted file mode 100644 index d0b6c9ed..00000000 --- a/guarantees/project/proposal/vote-on-proposal.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.proposal.vote-on-proposal.050 -journeyIndex: 50 -type: project -subtype: proposal -journey: Vote on Proposal -ownerPackage: "@treeseed/admin" -summary: Record review or approval decisions against proposals; approved decisions are required before acting mode can run. -status: active -dependencies: - journeys: - - 48 - guarantees: - - guarantee.project.proposal.create-proposal.048 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 48" -scene: - required: true - manifest: ./scenes/vote-on-proposal.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/proposals - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.proposal.vote-on-proposal.api -content: - required: true - verifierRefs: - - admin.project.proposal.vote-on-proposal.content -audit: - required: true - verifierRefs: - - admin.project.proposal.vote-on-proposal.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.proposal.vote-on-proposal.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Record review or approval decisions against proposals; approved decisions are required before acting mode can run. diff --git a/guarantees/project/question/answer-question.guarantee.yaml b/guarantees/project/question/answer-question.guarantee.yaml deleted file mode 100644 index 7af02013..00000000 --- a/guarantees/project/question/answer-question.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.question.answer-question.042 -journeyIndex: 42 -type: project -subtype: question -journey: Answer Question -ownerPackage: "@treeseed/admin" -summary: Create an answer or linked note with subject frontmatter; agent-generated answers must be traceable to execution and TreeDX context. -status: active -dependencies: - journeys: - - 38 - guarantees: - - guarantee.project.question.ask-question.038 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 38" -scene: - required: true - manifest: ./scenes/answer-question.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/questions/seed-question - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.question.answer-question.api -content: - required: true - verifierRefs: - - admin.project.question.answer-question.content -audit: - required: true - verifierRefs: - - admin.project.question.answer-question.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.question.answer-question.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create an answer or linked note with subject frontmatter; agent-generated answers must be traceable to execution and TreeDX context. diff --git a/guarantees/project/question/ask-question.guarantee.yaml b/guarantees/project/question/ask-question.guarantee.yaml deleted file mode 100644 index 2250eec7..00000000 --- a/guarantees/project/question/ask-question.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.question.ask-question.038 -journeyIndex: 38 -type: project -subtype: question -journey: Ask Question -ownerPackage: "@treeseed/admin" -summary: Create a project question as Knowledge Hub content through TreeDX and SDK content models; direct local-content writes are not allowed for agent-facing work. -status: active -dependencies: - journeys: - - 32 - guarantees: - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 32" -scene: - required: true - manifest: ./scenes/ask-question.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/questions/new - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.question.ask-question.api -content: - required: true - verifierRefs: - - admin.project.question.ask-question.content -audit: - required: true - verifierRefs: - - admin.project.question.ask-question.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.question.ask-question.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create a project question as Knowledge Hub content through TreeDX and SDK content models; direct local-content writes are not allowed for agent-facing work. diff --git a/guarantees/project/question/delete-question.guarantee.yaml b/guarantees/project/question/delete-question.guarantee.yaml deleted file mode 100644 index d9b0f7ed..00000000 --- a/guarantees/project/question/delete-question.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.question.delete-question.040 -journeyIndex: 40 -type: project -subtype: question -journey: Delete Question -ownerPackage: "@treeseed/admin" -summary: Delete or archive a question through TreeDX with relationship checks; should avoid breaking linked notes decisions and proposals. -status: active -dependencies: - journeys: - - 38 - guarantees: - - guarantee.project.question.ask-question.038 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 38" -scene: - required: true - manifest: ./scenes/delete-question.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/questions/seed-question - componentContract: destructive-confirmation service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.question.delete-question.api -content: - required: true - verifierRefs: - - admin.project.question.delete-question.content -audit: - required: true - verifierRefs: - - admin.project.question.delete-question.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.question.delete-question.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Delete or archive a question through TreeDX with relationship checks; should avoid breaking linked notes decisions and proposals. diff --git a/guarantees/project/question/edit-question.guarantee.yaml b/guarantees/project/question/edit-question.guarantee.yaml deleted file mode 100644 index 9314dfa1..00000000 --- a/guarantees/project/question/edit-question.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.question.edit-question.039 -journeyIndex: 39 -type: project -subtype: question -journey: Edit Question -ownerPackage: "@treeseed/admin" -summary: Edit question content through TreeDX with provenance and validation; should preserve links to answers notes proposals and workday context. -status: active -dependencies: - journeys: - - 38 - guarantees: - - guarantee.project.question.ask-question.038 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 38" -scene: - required: true - manifest: ./scenes/edit-question.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/questions/seed-question/edit - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.question.edit-question.api -content: - required: true - verifierRefs: - - admin.project.question.edit-question.content -audit: - required: true - verifierRefs: - - admin.project.question.edit-question.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.question.edit-question.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Edit question content through TreeDX with provenance and validation; should preserve links to answers notes proposals and workday context. diff --git a/guarantees/project/question/scenes/answer-question.scene.yaml b/guarantees/project/question/scenes/answer-question.scene.yaml deleted file mode 100644 index f8b7baba..00000000 --- a/guarantees/project/question/scenes/answer-question.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.question.answer-question.042 -title: Answer Question -description: Scene scaffold for guarantee.project.question.answer-question.042. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Answer Question opens the canonical @treeseed/admin dashboard read model workflow. - - Answer Question exercises a service journey instead of only loading /app/work/questions/seed-question. - - Answer Question records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Answer Question - action: - goto: /app/work/questions/seed-question - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Answer Question service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/question/scenes/ask-question.scene.yaml b/guarantees/project/question/scenes/ask-question.scene.yaml deleted file mode 100644 index c2cedf81..00000000 --- a/guarantees/project/question/scenes/ask-question.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.question.ask-question.038 -title: Ask Question -description: Scene scaffold for guarantee.project.question.ask-question.038. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Ask Question opens the canonical @treeseed/admin dashboard read model workflow. - - Ask Question exercises a service journey instead of only loading /app/work/questions/new. - - Ask Question records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Ask Question - action: - goto: /app/work/questions/new - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Ask Question service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/question/scenes/delete-question.scene.yaml b/guarantees/project/question/scenes/delete-question.scene.yaml deleted file mode 100644 index cfbc23a0..00000000 --- a/guarantees/project/question/scenes/delete-question.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.question.delete-question.040 -title: Delete Question -description: Scene scaffold for guarantee.project.question.delete-question.040. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Question opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Question exercises a service journey instead of only loading /app/work/questions/seed-question. - - Delete Question records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Question - action: - goto: /app/work/questions/seed-question - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Delete Question service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/question/scenes/edit-question.scene.yaml b/guarantees/project/question/scenes/edit-question.scene.yaml deleted file mode 100644 index 252c2c29..00000000 --- a/guarantees/project/question/scenes/edit-question.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.question.edit-question.039 -title: Edit Question -description: Scene scaffold for guarantee.project.question.edit-question.039. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Question opens the canonical @treeseed/admin full page form workflow. - - Edit Question exercises a service journey instead of only loading /app/work/questions/seed-question/edit. - - Edit Question records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Question - action: - goto: /app/work/questions/seed-question/edit - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Edit Question service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/question/scenes/search-questions-answers.scene.yaml b/guarantees/project/question/scenes/search-questions-answers.scene.yaml deleted file mode 100644 index 1dad0e52..00000000 --- a/guarantees/project/question/scenes/search-questions-answers.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: project.question.search-questions-answers.041 -title: Search Questions / Answers -description: Scene scaffold for guarantee.project.question.search-questions-answers.041. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Search Questions / Answers opens the canonical @treeseed/admin dashboard read model workflow. - - Search Questions / Answers exercises a service journey instead of only loading /app/work/questions/seed-question. - - Search Questions / Answers records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Search Questions / Answers - action: - goto: /app/work/questions/seed-question - expect: - urlIncludes: /app/work - - id: inspect-service-surface - title: Inspect Search Questions / Answers service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/work -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/project/question/search-questions-answers.guarantee.yaml b/guarantees/project/question/search-questions-answers.guarantee.yaml deleted file mode 100644 index 4a02a580..00000000 --- a/guarantees/project/question/search-questions-answers.guarantee.yaml +++ /dev/null @@ -1,73 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.project.question.search-questions-answers.041 -journeyIndex: 41 -type: project -subtype: question -journey: Search Questions / Answers -ownerPackage: "@treeseed/admin" -summary: Search project questions and answers through indexed content APIs or TreeDX-backed query surfaces; missing search should be implemented as a content service capability. -status: active -dependencies: - journeys: - - 38 - guarantees: - - guarantee.project.question.ask-question.038 -actors: - allowed: - - project_manager - - project_contributor - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 38" -scene: - required: true - manifest: ./scenes/search-questions-answers.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/work/questions/seed-question - componentContract: inline-form/search-panel service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.project.question.search-questions-answers.api -content: - required: true - verifierRefs: - - admin.project.question.search-questions-answers.content -audit: - required: true - verifierRefs: - - admin.project.question.search-questions-answers.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.project.question.search-questions-answers.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Search project questions and answers through indexed content APIs or TreeDX-backed query surfaces; missing search should be implemented as a content service capability. diff --git a/guarantees/project/site/deploy-standalone-admin-site.guarantee.yaml b/guarantees/project/site/deploy-standalone-admin-site.guarantee.yaml new file mode 100644 index 00000000..795481d5 --- /dev/null +++ b/guarantees/project/site/deploy-standalone-admin-site.guarantee.yaml @@ -0,0 +1,29 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.project.site.deploy-standalone-admin-site.754 +journeyIndex: 754 +type: project +subtype: site +journey: Deploy standalone Admin site +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Run Admin independently from Market against the public API and TreeDX-backed R2 content runtime. +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [Hosted deployment remains suspended pending reviewed OpenTofu acceptance.] +api: + required: true + verifierRefs: [] +content: + required: true + verifierRefs: [] +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: + - Package metadata is covered by tests/contract/package/admin-package.test.ts and npm run release:verify. + - Activation still requires isolated GitHub and Cloudflare reconciliation, deployed route, API, and R2 overlay evidence. diff --git a/guarantees/reconciliation/generated-team-guarantees.csv b/guarantees/reconciliation/generated-team-guarantees.csv new file mode 100644 index 00000000..a7c2d50b --- /dev/null +++ b/guarantees/reconciliation/generated-team-guarantees.csv @@ -0,0 +1,12 @@ +Guarantee ID,Journey Index,Type,Subtype,Journey,Owner Package,Surface,Status,Dependencies,Actor Roles,Forbidden Roles,Device Coverage,Preconditions,Scene Manifest,API Verifier Refs,Content Verifier Refs,Audit Verifier Refs,Negative Cases,Release Gates,Evidence Required,Notes,Source Path +guarantee.team.team.create-team.012,12,team,team,Create Team,@treeseed/admin,admin-ui,active,guarantee.user.auth.user-login.004; journey:4,verified_user,anonymous_user,desktop_chromium; tablet_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 4,../scenes/create-team.scene.yaml,api.team.create.correlated,,api.team.create.correlated,anonymous-denied,core; release,playwright_trace; scene_video; api_verification_log,Create the durable team identity and membership boundary used by active-team selection and team management.,packages/admin/guarantees/team/team/create-team.guarantee.yaml +guarantee.team.team.switch-active-team.013,13,team,team,Switch Active Team,@treeseed/admin,admin-ui,active,guarantee.team.team.create-team.012; journey:12,team_admin; team_owner,anonymous_user,desktop_chromium; tablet_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 12,../scenes/switch-active-team.scene.yaml,api.team.active.correlated,,,anonymous-denied,core; release,playwright_trace; scene_video; api_verification_log,Change the active team context used by admin and API requests; must refresh project capacity and membership-scoped views.,packages/admin/guarantees/team/team/switch-active-team.guarantee.yaml +guarantee.team.team.edit-team-settings.014,14,team,team,Edit Team Settings,@treeseed/admin,admin-ui,active,guarantee.team.team.switch-active-team.013; journey:13,team_admin; team_owner,contributor,desktop_chromium; tablet_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 12,../scenes/edit-team-settings.scene.yaml,api.team.update.correlated,,api.team.update.correlated,contributor-denied,core; release,playwright_trace; scene_video; api_verification_log,Update team metadata and policy knobs; should not mutate package or provider infrastructure directly.,packages/admin/guarantees/team/team/edit-team-settings.guarantee.yaml +guarantee.team.team.view-team-overview.015,15,team,team,View Team Overview,@treeseed/admin,admin-ui,active,guarantee.team.team.edit-team-settings.014; journey:14,team_member,anonymous_user; non_member,desktop_chromium; tablet_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 12,../scenes/view-team-overview.scene.yaml,api.team.overview.correlated,,,anonymous-denied; non-member-denied,core; release,playwright_trace; scene_video; api_verification_log,Public identity is covered separately by guarantee.team.team.view-public-team-profile.021.,packages/admin/guarantees/team/team/view-team-overview.guarantee.yaml +guarantee.team.membership.invite-team-members.017,17,team,membership,Invite Team Members,@treeseed/admin,admin-ui,active,guarantee.team.team.edit-team-settings.014; journey:14,team_admin; team_owner,contributor,desktop_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 12,./scenes/invite-team-members.scene.yaml,api.team.invite.correlated,,api.team.invite.correlated,contributor-denied,core; release,playwright_trace; scene_video; api_verification_log,Create team invitation records and send notices; roles should map to API/admin authorization rather than client-only checks.,packages/admin/guarantees/team/membership/invite-team-members.guarantee.yaml +guarantee.team.membership.accept-team-invitation.018,18,team,membership,Accept Team Invitation,@treeseed/admin,admin-ui,active,guarantee.team.membership.invite-team-members.017; journey:17,invited_user,mismatched_user,desktop_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 17,./scenes/accept-team-invitation.scene.yaml,api.team.accept.correlated,,api.team.accept.correlated,mismatched-user-denied; invalid-expired-revoked-replay,core; release,playwright_trace; scene_video; api_verification_log,Redeem an invite and attach the user to the team; should handle authenticated and newly registered users cleanly.,packages/admin/guarantees/team/membership/accept-team-invitation.guarantee.yaml +guarantee.team.membership.change-member-role.019,19,team,membership,Change Member Role,@treeseed/admin,admin-ui,active,guarantee.team.membership.accept-team-invitation.018; journey:18,team_admin; team_owner,contributor,desktop_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 18,./scenes/change-member-role.scene.yaml,api.team.role.correlated,,api.team.role.correlated,contributor-denied,core; release,playwright_trace; scene_video; api_verification_log,Update membership role with authorization and last-owner protections; changes should immediately affect API permission decisions.,packages/admin/guarantees/team/membership/change-member-role.guarantee.yaml +guarantee.team.membership.remove-team-member.020,20,team,membership,Remove Team Member,@treeseed/admin,admin-ui,active,guarantee.team.membership.change-member-role.019; journey:19,team_admin; team_owner,contributor,desktop_chromium; mobile_chromium,integrated_treeseed_project; Journey dependencies must be satisfied: 18,./scenes/remove-team-member.scene.yaml,api.team.remove.correlated,,api.team.remove.correlated,contributor-denied,core; release,playwright_trace; scene_video; api_verification_log,Remove or deactivate a team member with auditability; must avoid orphaning owned projects decisions or running workdays.,packages/admin/guarantees/team/membership/remove-team-member.guarantee.yaml +guarantee.team.team.view-public-team-profile.021,,team,team,View Public Team Profile,@treeseed/admin,admin-ui,active,guarantee.team.team.edit-team-settings.014; journey:14,anonymous_user,,desktop_chromium; tablet_chromium; mobile_chromium,integrated_treeseed_project; The owning team identity must already exist.,../scenes/view-public-team-profile.scene.yaml,api.team.public-profile.correlated,,,archived-not-found,core; release,playwright_trace; scene_video; api_verification_log,"This supplemental guarantee intentionally has no CSV journey index.; Public projects, templates, knowledge packs, and their publication trail are explicit public projections, never private operational aggregates.",packages/admin/guarantees/team/team/view-public-team-profile.guarantee.yaml +guarantee.team.team.delete-team.016,16,team,team,Delete Team,@treeseed/admin,admin-ui,active,guarantee.team.membership.remove-team-member.020; guarantee.team.team.view-public-team-profile.021,team_admin; team_owner,project_lead,desktop_chromium; mobile_chromium,integrated_treeseed_project; Membership lifecycle and public profile verification must finish before deletion.,../scenes/delete-team.scene.yaml,api.team.delete.correlated,,api.team.delete.correlated,project-lead-denied,core; release,playwright_trace; scene_video; api_verification_log,"Archiving is reversible during the displayed recovery window; permanent deletion is separately available without an archive delay and requires blocker checks, the exact team name, and the current password.",packages/admin/guarantees/team/team/delete-team.guarantee.yaml +guarantee.team.team.team-management-production-readiness.022,,team,team,Team Management Production Readiness,@treeseed/admin,scene,active,guarantee.team.team.view-public-team-profile.021; journey:12; journey:13; journey:14; journey:15; journey:16; journey:17; journey:18; journey:19; journey:20,release_operator,,desktop_chromium; mobile_chromium,integrated_treeseed_project; Every required feature guarantee must be active and pass against the same current source closure.,,admin.team.production-readiness; admin.team.ui-contracts; api.team.lifecycle-contracts; sdk.team.ui-evidence-trust,,,stale-or-mismatched-evidence-denied,core; release,execution_graph; api_verification_log; cleanup_report,"Fails closed unless every required team guarantee, feature contract, current-source verifier, and cleanup check passes.",packages/admin/guarantees/team/team/team-management-production-readiness.guarantee.yaml diff --git a/guarantees/reconciliation/treeseed-journeys-12-20.yaml b/guarantees/reconciliation/treeseed-journeys-12-20.yaml new file mode 100644 index 00000000..d390c582 --- /dev/null +++ b/guarantees/reconciliation/treeseed-journeys-12-20.yaml @@ -0,0 +1,78 @@ +schemaVersion: treeseed.guarantee-reconciliation/v1 +ownerPackage: "@treeseed/admin" +requirementsInput: /home/adrian/Downloads/treeseed.journeys.csv +scope: [12, 13, 14, 15, 16, 17, 18, 19, 20] +generatedFrom: package-local guarantee manifests +status: active +notes: + - The downloaded CSV is requirements input and was not edited. + - Current routes and execution keys are canonical in the package manifests. + - Journey 15 is the authenticated operational overview. The anonymous redacted profile is supplemental guarantee 021. + - Active status authorizes current-source execution; every run still fails closed unless rendered positive and forbidden-actor scenes, correlated API/audit evidence, exact devices, and cleanup pass. +journeys: + - index: 12 + id: guarantee.team.team.create-team.012 + inputRoute: /admin/teams/:teamId/create-team + canonicalRoute: /app/teams/new + executionKey: admin.team.create + correction: Creation has no pre-existing team identifier and does not implicitly select the new team. + - index: 13 + id: guarantee.team.team.switch-active-team.013 + inputRoute: /admin/teams/:teamId/switch-active-team + canonicalRoute: /app/teams + actionRoute: /app/teams/active + executionKey: admin.team.select-active + correction: Active selection is an explicit membership-validated action and never a page-visit side effect. + - index: 14 + id: guarantee.team.team.edit-team-settings.014 + inputRoute: /admin/teams/:teamId/edit-team-settings + canonicalRoute: /app/teams/[teamId]/edit + executionKey: admin.team.edit + correction: Settings include identity, visibility, validation, conflict, authorization, preview, and reload persistence. + - index: 15 + id: guarantee.team.team.view-team-overview.015 + inputId: guarantee.team.team.view-team-profile.015 + inputJourney: View Team Profile + inputRoute: /admin/teams/:teamId/view-team-profile + canonicalRoute: /app/teams/[teamId] + executionKey: admin.team.overview + correction: This is the authenticated operational overview; it is not the anonymous public profile. + - index: 16 + id: guarantee.team.team.delete-team.016 + inputRoute: /admin/teams/:teamId/delete-team + canonicalRoute: /app/teams/[teamId]/delete + executionKey: admin.team.delete + correction: The lifecycle separates reversible archive and restore with a timezone-aware recovery countdown from immediate permanent deletion guarded by blockers, exact-name confirmation, and reauthentication. + - index: 17 + id: guarantee.team.membership.invite-team-members.017 + inputRoute: /admin/teams/:teamId/invite-team-members + canonicalRoute: /app/teams/[teamId]/members + executionKey: admin.team.invite + correction: Pending invitations are visible and support accurate send, resend, revoke, expiry, and audit states. + - index: 18 + id: guarantee.team.membership.accept-team-invitation.018 + inputRoute: /admin/teams/:teamId/accept-team-invitation + canonicalRoute: /team-invites/[token]/accept + executionKey: admin.team.accept-invite + correction: GET previews consent state; a CSRF-protected POST accepts for the exact verified recipient. + - index: 19 + id: guarantee.team.membership.change-member-role.019 + inputRoute: /admin/teams/:teamId/change-member-role + canonicalRoute: /app/teams/[teamId]/members + executionKey: admin.team.change-member-role + correction: Role changes prove owner restrictions, last-owner safety, visible-control changes, and API permission changes. + - index: 20 + id: guarantee.team.membership.remove-team-member.020 + inputRoute: /admin/teams/:teamId/remove-team-member + canonicalRoute: /app/teams/[teamId]/members + executionKey: admin.team.remove-member + correction: Removal and self-leave expose blockers, require confirmation, preserve the last owner, and prove lost access. +supplemental: + - id: guarantee.team.team.view-public-team-profile.021 + journeyIndex: null + route: /t/[name] + executionKey: admin.team.public-profile + purpose: Anonymous active-team identity-only profile with operational and membership redaction. + - id: guarantee.team.team.team-management-production-readiness.022 + journeyIndex: null + purpose: Release-required aggregate over the feature contract and all team journeys. diff --git a/guarantees/security/accounts/export-account-data.guarantee.yaml b/guarantees/security/accounts/export-account-data.guarantee.yaml new file mode 100644 index 00000000..471fa81a --- /dev/null +++ b/guarantees/security/accounts/export-account-data.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.accounts.export-account-data.617 +journeyIndex: 617 +type: security +subtype: accounts +journey: "Export account data" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can export account data." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/accounts/manage-account-email-addresses.guarantee.yaml b/guarantees/security/accounts/manage-account-email-addresses.guarantee.yaml new file mode 100644 index 00000000..056fa928 --- /dev/null +++ b/guarantees/security/accounts/manage-account-email-addresses.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.accounts.manage-account-email-addresses.616 +journeyIndex: 616 +type: security +subtype: accounts +journey: "Manage account email addresses" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can manage account email addresses." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/accounts/recover-an-account-with-changed-identity-details.guarantee.yaml b/guarantees/security/accounts/recover-an-account-with-changed-identity-details.guarantee.yaml new file mode 100644 index 00000000..0220d995 --- /dev/null +++ b/guarantees/security/accounts/recover-an-account-with-changed-identity-details.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.accounts.recover-an-account-with-changed-identity-details.619 +journeyIndex: 619 +type: security +subtype: accounts +journey: "Recover an account with changed identity details" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can recover an account with changed identity details." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/accounts/transfer-responsibilities-before-account-deletion.guarantee.yaml b/guarantees/security/accounts/transfer-responsibilities-before-account-deletion.guarantee.yaml new file mode 100644 index 00000000..2ab66389 --- /dev/null +++ b/guarantees/security/accounts/transfer-responsibilities-before-account-deletion.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.accounts.transfer-responsibilities-before-account-deletion.618 +journeyIndex: 618 +type: security +subtype: accounts +journey: "Transfer responsibilities before account deletion" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can transfer responsibilities before account deletion." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/authentication/complete-a-multi-factor-challenge.guarantee.yaml b/guarantees/security/authentication/complete-a-multi-factor-challenge.guarantee.yaml new file mode 100644 index 00000000..653fd251 --- /dev/null +++ b/guarantees/security/authentication/complete-a-multi-factor-challenge.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.authentication.complete-a-multi-factor-challenge.611 +journeyIndex: 611 +type: security +subtype: authentication +journey: "Complete a multi-factor challenge" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can complete a multi-factor challenge." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/authentication/enroll-multi-factor-authentication.guarantee.yaml b/guarantees/security/authentication/enroll-multi-factor-authentication.guarantee.yaml new file mode 100644 index 00000000..f960f7f6 --- /dev/null +++ b/guarantees/security/authentication/enroll-multi-factor-authentication.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.authentication.enroll-multi-factor-authentication.610 +journeyIndex: 610 +type: security +subtype: authentication +journey: "Enroll multi-factor authentication" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can enroll multi-factor authentication." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/authentication/link-an-external-identity-provider.guarantee.yaml b/guarantees/security/authentication/link-an-external-identity-provider.guarantee.yaml new file mode 100644 index 00000000..9aaec6ac --- /dev/null +++ b/guarantees/security/authentication/link-an-external-identity-provider.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.authentication.link-an-external-identity-provider.613 +journeyIndex: 613 +type: security +subtype: authentication +journey: "Link an external identity provider" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can link an external identity provider." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/authentication/preserve-safe-authentication-return-paths.guarantee.yaml b/guarantees/security/authentication/preserve-safe-authentication-return-paths.guarantee.yaml new file mode 100644 index 00000000..18787390 --- /dev/null +++ b/guarantees/security/authentication/preserve-safe-authentication-return-paths.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.authentication.preserve-safe-authentication-return-paths.615 +journeyIndex: 615 +type: security +subtype: authentication +journey: "Preserve safe authentication return paths" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can preserve safe authentication return paths." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/authentication/recover-multi-factor-access.guarantee.yaml b/guarantees/security/authentication/recover-multi-factor-access.guarantee.yaml new file mode 100644 index 00000000..ac9488c9 --- /dev/null +++ b/guarantees/security/authentication/recover-multi-factor-access.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.authentication.recover-multi-factor-access.612 +journeyIndex: 612 +type: security +subtype: authentication +journey: "Recover multi-factor access" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can recover multi-factor access." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/authentication/require-recent-authentication-for-sensitive-actions.guarantee.yaml b/guarantees/security/authentication/require-recent-authentication-for-sensitive-actions.guarantee.yaml new file mode 100644 index 00000000..2c18f07b --- /dev/null +++ b/guarantees/security/authentication/require-recent-authentication-for-sensitive-actions.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.authentication.require-recent-authentication-for-sensitive-actions.609 +journeyIndex: 609 +type: security +subtype: authentication +journey: "Require recent authentication for sensitive actions" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can require recent authentication for sensitive actions." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/authentication/throttle-repeated-authentication-failures.guarantee.yaml b/guarantees/security/authentication/throttle-repeated-authentication-failures.guarantee.yaml new file mode 100644 index 00000000..80a4fb3b --- /dev/null +++ b/guarantees/security/authentication/throttle-repeated-authentication-failures.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.authentication.throttle-repeated-authentication-failures.614 +journeyIndex: 614 +type: security +subtype: authentication +journey: "Throttle repeated authentication failures" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can throttle repeated authentication failures." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/monitoring-auditing/correlate-user-and-service-activity.guarantee.yaml b/guarantees/security/monitoring-auditing/correlate-user-and-service-activity.guarantee.yaml new file mode 100644 index 00000000..a8af4119 --- /dev/null +++ b/guarantees/security/monitoring-auditing/correlate-user-and-service-activity.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.monitoring-auditing.correlate-user-and-service-activity.633 +journeyIndex: 633 +type: security +subtype: monitoring-auditing +journey: "Correlate user and service activity" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can correlate user and service activity." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/monitoring-auditing/detect-suspicious-access-patterns.guarantee.yaml b/guarantees/security/monitoring-auditing/detect-suspicious-access-patterns.guarantee.yaml new file mode 100644 index 00000000..ec1891b8 --- /dev/null +++ b/guarantees/security/monitoring-auditing/detect-suspicious-access-patterns.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.monitoring-auditing.detect-suspicious-access-patterns.636 +journeyIndex: 636 +type: security +subtype: monitoring-auditing +journey: "Detect suspicious access patterns" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can detect suspicious access patterns." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/monitoring-auditing/export-privacy-safe-audit-evidence.guarantee.yaml b/guarantees/security/monitoring-auditing/export-privacy-safe-audit-evidence.guarantee.yaml new file mode 100644 index 00000000..eca20f05 --- /dev/null +++ b/guarantees/security/monitoring-auditing/export-privacy-safe-audit-evidence.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.monitoring-auditing.export-privacy-safe-audit-evidence.634 +journeyIndex: 634 +type: security +subtype: monitoring-auditing +journey: "Export privacy-safe audit evidence" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can export privacy-safe audit evidence." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/monitoring-auditing/inspect-platform-health.guarantee.yaml b/guarantees/security/monitoring-auditing/inspect-platform-health.guarantee.yaml new file mode 100644 index 00000000..bf386297 --- /dev/null +++ b/guarantees/security/monitoring-auditing/inspect-platform-health.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.monitoring-auditing.inspect-platform-health.631 +journeyIndex: 631 +type: security +subtype: monitoring-auditing +journey: "Inspect platform health" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can inspect platform health." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/monitoring-auditing/retain-audit-evidence-by-policy.guarantee.yaml b/guarantees/security/monitoring-auditing/retain-audit-evidence-by-policy.guarantee.yaml new file mode 100644 index 00000000..963af400 --- /dev/null +++ b/guarantees/security/monitoring-auditing/retain-audit-evidence-by-policy.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.monitoring-auditing.retain-audit-evidence-by-policy.635 +journeyIndex: 635 +type: security +subtype: monitoring-auditing +journey: "Retain audit evidence by policy" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can retain audit evidence by policy." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/monitoring-auditing/review-failed-operation-diagnostics.guarantee.yaml b/guarantees/security/monitoring-auditing/review-failed-operation-diagnostics.guarantee.yaml new file mode 100644 index 00000000..aa7e0612 --- /dev/null +++ b/guarantees/security/monitoring-auditing/review-failed-operation-diagnostics.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.monitoring-auditing.review-failed-operation-diagnostics.637 +journeyIndex: 637 +type: security +subtype: monitoring-auditing +journey: "Review failed operation diagnostics" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can review failed operation diagnostics." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/monitoring-auditing/search-security-audit-events.guarantee.yaml b/guarantees/security/monitoring-auditing/search-security-audit-events.guarantee.yaml new file mode 100644 index 00000000..23a36cae --- /dev/null +++ b/guarantees/security/monitoring-auditing/search-security-audit-events.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.monitoring-auditing.search-security-audit-events.632 +journeyIndex: 632 +type: security +subtype: monitoring-auditing +journey: "Search security audit events" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can search security audit events." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/service-vault/audit-secret-access-without-revealing-values.guarantee.yaml b/guarantees/security/service-vault/audit-secret-access-without-revealing-values.guarantee.yaml new file mode 100644 index 00000000..b10f5124 --- /dev/null +++ b/guarantees/security/service-vault/audit-secret-access-without-revealing-values.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.service-vault.audit-secret-access-without-revealing-values.629 +journeyIndex: 629 +type: security +subtype: service-vault +journey: "Audit secret access without revealing values" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can audit secret access without revealing values." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/service-vault/create-a-team-service-vault.guarantee.yaml b/guarantees/security/service-vault/create-a-team-service-vault.guarantee.yaml new file mode 100644 index 00000000..c7563921 --- /dev/null +++ b/guarantees/security/service-vault/create-a-team-service-vault.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.service-vault.create-a-team-service-vault.625 +journeyIndex: 625 +type: security +subtype: service-vault +journey: "Create a team service vault" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can create a team service vault." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/service-vault/destroy-a-service-vault-safely.guarantee.yaml b/guarantees/security/service-vault/destroy-a-service-vault-safely.guarantee.yaml new file mode 100644 index 00000000..0b1f6a4e --- /dev/null +++ b/guarantees/security/service-vault/destroy-a-service-vault-safely.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.service-vault.destroy-a-service-vault-safely.630 +journeyIndex: 630 +type: security +subtype: service-vault +journey: "Destroy a service vault safely" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can destroy a service vault safely." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/service-vault/grant-scoped-vault-access.guarantee.yaml b/guarantees/security/service-vault/grant-scoped-vault-access.guarantee.yaml new file mode 100644 index 00000000..6a3378db --- /dev/null +++ b/guarantees/security/service-vault/grant-scoped-vault-access.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.service-vault.grant-scoped-vault-access.626 +journeyIndex: 626 +type: security +subtype: service-vault +journey: "Grant scoped vault access" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can grant scoped vault access." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/service-vault/revoke-a-stored-service-credential.guarantee.yaml b/guarantees/security/service-vault/revoke-a-stored-service-credential.guarantee.yaml new file mode 100644 index 00000000..6d898ad5 --- /dev/null +++ b/guarantees/security/service-vault/revoke-a-stored-service-credential.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.service-vault.revoke-a-stored-service-credential.628 +journeyIndex: 628 +type: security +subtype: service-vault +journey: "Revoke a stored service credential" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can revoke a stored service credential." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/service-vault/rotate-a-stored-service-credential.guarantee.yaml b/guarantees/security/service-vault/rotate-a-stored-service-credential.guarantee.yaml new file mode 100644 index 00000000..2ad75d74 --- /dev/null +++ b/guarantees/security/service-vault/rotate-a-stored-service-credential.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.service-vault.rotate-a-stored-service-credential.627 +journeyIndex: 627 +type: security +subtype: service-vault +journey: "Rotate a stored service credential" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can rotate a stored service credential." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/teams/archive-and-restore-a-team.guarantee.yaml b/guarantees/security/teams/archive-and-restore-a-team.guarantee.yaml new file mode 100644 index 00000000..0f3e0762 --- /dev/null +++ b/guarantees/security/teams/archive-and-restore-a-team.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.teams.archive-and-restore-a-team.623 +journeyIndex: 623 +type: security +subtype: teams +journey: "Archive and restore a team" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can archive and restore a team." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/teams/manage-team-profile-visibility.guarantee.yaml b/guarantees/security/teams/manage-team-profile-visibility.guarantee.yaml new file mode 100644 index 00000000..9ea5e526 --- /dev/null +++ b/guarantees/security/teams/manage-team-profile-visibility.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.teams.manage-team-profile-visibility.622 +journeyIndex: 622 +type: security +subtype: teams +journey: "Manage team profile visibility" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can manage team profile visibility." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/teams/protect-the-last-team-owner.guarantee.yaml b/guarantees/security/teams/protect-the-last-team-owner.guarantee.yaml new file mode 100644 index 00000000..a89fa940 --- /dev/null +++ b/guarantees/security/teams/protect-the-last-team-owner.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.teams.protect-the-last-team-owner.621 +journeyIndex: 621 +type: security +subtype: teams +journey: "Protect the last team owner" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can protect the last team owner." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/teams/resend-or-cancel-a-team-invitation.guarantee.yaml b/guarantees/security/teams/resend-or-cancel-a-team-invitation.guarantee.yaml new file mode 100644 index 00000000..6bcc0a98 --- /dev/null +++ b/guarantees/security/teams/resend-or-cancel-a-team-invitation.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.teams.resend-or-cancel-a-team-invitation.620 +journeyIndex: 620 +type: security +subtype: teams +journey: "Resend or cancel a team invitation" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can resend or cancel a team invitation." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/security/teams/review-team-membership-history.guarantee.yaml b/guarantees/security/teams/review-team-membership-history.guarantee.yaml new file mode 100644 index 00000000..3f349979 --- /dev/null +++ b/guarantees/security/teams/review-team-membership-history.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.security.teams.review-team-membership-history.624 +journeyIndex: 624 +type: security +subtype: teams +journey: "Review team membership history" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "Guarantee that TreeSeed can review team membership history." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, platform_admin], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: [] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: [] +evidence: { required: [guarantee_report] } +notes: ["Planned from the TreeSeed Guide platform coverage audit."] diff --git a/guarantees/service/connection/connect-service.guarantee.yaml b/guarantees/service/connection/connect-service.guarantee.yaml new file mode 100644 index 00000000..89a3fbcd --- /dev/null +++ b/guarantees/service/connection/connect-service.guarantee.yaml @@ -0,0 +1,53 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.service.connection.connect-service.023 +journeyIndex: 23 +type: service +subtype: connection +journey: Connect Service +ownerPackage: "@treeseed/admin" +summary: Connect a provider account through the rendered UI and enable independent service capabilities. +status: blocked +dependencies: + journeys: [22] + guarantees: [guarantee.service.vault.recover-vault-access.022] +actors: + allowed: [team_owner, project_lead, service_admin] + forbidden: [anonymous_user, non_member, contributor, viewer] +devices: + required: [desktop_chromium, tablet_chromium, mobile_chromium] +gates: [security, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [An active team and initialized service vault exist.] +notes: + - Blocked because the shared lifecycle scene still targets the removed manual GitHub App credential path; current-source Connector and token-authority scenes must pass before reactivation. +uiFeature: + contract: ../service-management.ui-feature.yaml + capabilities: [service.navigation, service.connect] +scene: + required: true + manifest: ./scenes/service-lifecycle.scene.yaml + executionKey: admin.services.connection-lifecycle + entryRoute: /app/services + componentContract: provider-first connection service journey + expectedEvidence: [playwright_trace, scene_video, screenshot_on_failure, console_log, network_log] +api: + required: true + verifierRefs: [api.service.management.contracts] +content: + required: false + verifierRefs: [] +audit: + required: true + verifierRefs: [api.service.management.contracts] +negativeCases: + - { id: anonymous-denied, actor: anonymous_user, sceneManifest: ../scenes/negative/anonymous-services.scene.yaml, executionKey: admin.services.negative.anonymous, verifierRefs: [api.service.management.contracts] } + - { id: nonmember-denied, actor: non_member, sceneManifest: ../scenes/negative/nonmember-services.scene.yaml, executionKey: admin.services.negative.nonmember, verifierRefs: [api.service.management.contracts] } + - { id: contributor-denied, actor: contributor, sceneManifest: ../scenes/negative/readonly-services.scene.yaml, executionKey: admin.services.negative.contributor, verifierRefs: [api.service.management.contracts] } + - { id: viewer-denied, actor: viewer, sceneManifest: ../scenes/negative/viewer-services.scene.yaml, executionKey: admin.services.negative.viewer, verifierRefs: [api.service.management.contracts] } +evidence: + required: [playwright_trace, scene_video, api_verification_log] +surface: admin-ui +run: + timeoutSeconds: 300 + requiredForRelease: true diff --git a/guarantees/service/connection/disconnect-service.guarantee.yaml b/guarantees/service/connection/disconnect-service.guarantee.yaml new file mode 100644 index 00000000..31b0db63 --- /dev/null +++ b/guarantees/service/connection/disconnect-service.guarantee.yaml @@ -0,0 +1,53 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.service.connection.disconnect-service.025 +journeyIndex: 25 +type: service +subtype: connection +journey: Disconnect Service +ownerPackage: "@treeseed/admin" +summary: Disconnect a provider only after dependency checks and revoke every run-owned ciphertext record. +status: blocked +dependencies: + journeys: [24] + guarantees: [guarantee.service.connection.edit-service.024] +actors: + allowed: [team_owner, project_lead, service_admin] + forbidden: [anonymous_user, non_member, contributor, viewer] +devices: + required: [desktop_chromium, tablet_chromium, mobile_chromium] +gates: [security, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [The run-owned provider connection and encrypted profile exist.] +notes: + - Blocked with the shared connection lifecycle until its removed credential selectors and provider evidence are replaced. +uiFeature: + contract: ../service-management.ui-feature.yaml + capabilities: [service.disconnect] +scene: + required: true + manifest: ./scenes/service-lifecycle.scene.yaml + executionKey: admin.services.connection-lifecycle + entryRoute: /app/services + componentContract: dependency-aware disconnection service journey + expectedEvidence: [playwright_trace, scene_video, screenshot_on_failure, console_log, network_log] +api: + required: true + verifierRefs: [api.service.management.contracts, api.service.management.run-cleanup] +content: + required: false + verifierRefs: [] +audit: + required: true + verifierRefs: [api.service.management.contracts] +negativeCases: + - { id: anonymous-denied, actor: anonymous_user, sceneManifest: ../scenes/negative/anonymous-services.scene.yaml, executionKey: admin.services.negative.anonymous, verifierRefs: [api.service.management.contracts] } + - { id: nonmember-denied, actor: non_member, sceneManifest: ../scenes/negative/nonmember-services.scene.yaml, executionKey: admin.services.negative.nonmember, verifierRefs: [api.service.management.contracts] } + - { id: contributor-denied, actor: contributor, sceneManifest: ../scenes/negative/readonly-services.scene.yaml, executionKey: admin.services.negative.contributor, verifierRefs: [api.service.management.contracts] } + - { id: viewer-denied, actor: viewer, sceneManifest: ../scenes/negative/viewer-services.scene.yaml, executionKey: admin.services.negative.viewer, verifierRefs: [api.service.management.contracts] } +evidence: + required: [playwright_trace, scene_video, api_verification_log] +surface: admin-ui +run: + timeoutSeconds: 300 + requiredForRelease: true diff --git a/guarantees/service/connection/edit-service.guarantee.yaml b/guarantees/service/connection/edit-service.guarantee.yaml new file mode 100644 index 00000000..748f7674 --- /dev/null +++ b/guarantees/service/connection/edit-service.guarantee.yaml @@ -0,0 +1,54 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.service.connection.edit-service.024 +journeyIndex: 24 +type: service +subtype: connection +journey: Edit Service +ownerPackage: "@treeseed/admin" +summary: Edit service metadata and capability bindings and store only context-bound browser-encrypted credentials. +status: blocked +dependencies: + journeys: [23] + guarantees: [guarantee.service.connection.connect-service.023] +actors: + allowed: [team_owner, project_lead, service_admin] + forbidden: [anonymous_user, non_member, contributor, viewer, ungranted_service_admin] +devices: + required: [desktop_chromium, tablet_chromium, mobile_chromium] +gates: [security, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [A run-owned provider connection exists.] +notes: + - Blocked until the rendered capability-profile selector, managed Connector flow, and explicit token authority are exercised by current-source scenes. +uiFeature: + contract: ../service-management.ui-feature.yaml + capabilities: [service.edit, service.credentials] +scene: + required: true + manifest: ./scenes/service-lifecycle.scene.yaml + executionKey: admin.services.connection-lifecycle + entryRoute: /app/services + componentContract: encrypted connection editing service journey + expectedEvidence: [playwright_trace, scene_video, screenshot_on_failure, console_log, network_log] +api: + required: true + verifierRefs: [api.service.management.contracts, sdk.service.vault.crypto] +content: + required: false + verifierRefs: [] +audit: + required: true + verifierRefs: [api.service.management.contracts] +negativeCases: + - { id: anonymous-denied, actor: anonymous_user, sceneManifest: ../scenes/negative/anonymous-services.scene.yaml, executionKey: admin.services.negative.anonymous, verifierRefs: [api.service.management.contracts] } + - { id: nonmember-denied, actor: non_member, sceneManifest: ../scenes/negative/nonmember-services.scene.yaml, executionKey: admin.services.negative.nonmember, verifierRefs: [api.service.management.contracts] } + - { id: contributor-denied, actor: contributor, sceneManifest: ../scenes/negative/readonly-services.scene.yaml, executionKey: admin.services.negative.contributor, verifierRefs: [api.service.management.contracts] } + - { id: viewer-denied, actor: viewer, sceneManifest: ../scenes/negative/viewer-services.scene.yaml, executionKey: admin.services.negative.viewer, verifierRefs: [api.service.management.contracts] } + - { id: ungranted-admin-denied, actor: ungranted_service_admin, sceneManifest: ../scenes/negative/vault-administrator-denial.scene.yaml, executionKey: admin.services.negative.ungranted-admin, verifierRefs: [api.service.management.contracts] } +evidence: + required: [playwright_trace, scene_video, api_verification_log] +surface: admin-ui +run: + timeoutSeconds: 300 + requiredForRelease: true diff --git a/guarantees/service/connection/remote-provider-management.guarantee.yaml b/guarantees/service/connection/remote-provider-management.guarantee.yaml new file mode 100644 index 00000000..f8151c67 --- /dev/null +++ b/guarantees/service/connection/remote-provider-management.guarantee.yaml @@ -0,0 +1,27 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.service.connection.remote-provider-management.731 +journeyIndex: 731 +type: service +subtype: connection +journey: Remote Provider Management +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Team service administrators authorize independent GitHub Repository and Workflow Connectors through rendered controls and inspect exact readiness and drift. +status: blocked +dependencies: + guarantees: [guarantee.service.connection.connect-service.023] +actors: + allowed: [team_owner, service_admin] + forbidden: [anonymous_user, non_member, contributor, viewer] +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [security, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [Dedicated acceptance GitHub App installations and a reconciled callback tunnel are required.] +scene: { required: false } +api: { required: true, verifierRefs: [] } +audit: { required: true, verifierRefs: [] } +negativeCases: [] +evidence: { required: [playwright_trace, api_verification_log, audit_log, cleanup_report] } +notes: + - Blocked until the live disposable-repository connector scene and run-correlated provider verifiers are implemented and pass twice. diff --git a/guarantees/service/connection/scenes/service-lifecycle.scene.yaml b/guarantees/service/connection/scenes/service-lifecycle.scene.yaml new file mode 100644 index 00000000..10ceec74 --- /dev/null +++ b/guarantees/service/connection/scenes/service-lifecycle.scene.yaml @@ -0,0 +1,260 @@ +schemaVersion: treeseed.scene/v1 +id: service.connection.service-lifecycle.023-025 +title: Connect, configure, encrypt, and disconnect a provider service +description: Exercises one run-owned GitHub connection through the complete rendered UI lifecycle. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.navigation, service.connect, service.edit, service.credentials, service.disconnect] + minimumSteps: 21 + requiresInteractiveAction: true + consumesState: + - key: team.active-session + kind: browser-storage + - key: team.primary + kind: marker + - key: services.team-vault + kind: marker + producesState: + - key: services.primary-connection + kind: marker + value: + provider: github + displayName: Guarantee GitHub {{runShort}} {{deviceId}} + status: disconnected +mode: + test: true + demo: true + training: true +target: + app: market + environment: local + baseUrl: auto + browser: chromium +devices: + defaultProfile: desktop_chromium + profiles: + - id: desktop_chromium + title: Desktop Chromium + viewport: { width: 1600, height: 900 } + video: { width: 1600, height: 900 } + output: { width: 1920, height: 1080 } + deviceScaleFactor: 1 + isMobile: false + hasTouch: false + - id: tablet_chromium + title: Tablet Chromium + viewport: { width: 820, height: 1180 } + video: { width: 820, height: 1180 } + output: { width: 820, height: 1180 } + deviceScaleFactor: 2 + isMobile: true + hasTouch: true + - id: mobile_chromium + title: Mobile Chromium + viewport: { width: 390, height: 844 } + video: { width: 390, height: 844 } + output: { width: 390, height: 844 } + deviceScaleFactor: 2 + isMobile: true + hasTouch: true +setup: + dev: { required: true, reuseExisting: true } + auth: { role: owner, required: true } +artifacts: + trace: true + video: true + screenshots: true + console: true + network: true + timeline: true + appLogs: true +workflow: + - id: open-provider + title: Choose GitHub from the provider gallery + action: { goto: /app/services/new?provider=github } + expect: + urlIncludes: /app/services/new + visible: + - { css: '[data-scene="service.create.submit"]', internal: true } + - id: reject-empty-connection + title: Reject missing provider identity fields + action: + click: { role: button, name: Connect service } + expect: + urlIncludes: /app/services/new + notText: Service connected. + - id: fill-connection-name + title: Name the run-owned provider connection + action: + fill: + css: '[data-scene="service.create.submit"] input[name="displayName"]' + internal: true + value: Guarantee GitHub {{runShort}} {{deviceId}} + expect: + visible: + - { css: '[data-scene="service.create.submit"]', internal: true } + - id: fill-organization + title: Enter non-sensitive provider identity metadata + action: + fill: + css: 'input[name="config.organization"]' + internal: true + value: guarantee-{{runShort}} + expect: + visible: + - { css: 'input[name="config.organization"]', internal: true } + - id: fill-app-id + title: Enter the public GitHub App identifier + action: + fill: + css: 'input[name="config.appId"]' + internal: true + value: "123456" + expect: + visible: + - { css: 'input[name="config.appId"]', internal: true } + - id: fill-installation-id + title: Enter the public installation identifier + action: + fill: + css: 'input[name="config.installationId"]' + internal: true + value: "654321" + expect: + visible: + - { css: 'input[name="config.installationId"]', internal: true } + - id: select-repository-capability + title: Enable repository hosting independently + action: + click: + css: 'input[name="capabilities"][value="repository-hosting"]' + internal: true + expect: + visible: + - { css: 'input[name="capabilities"][value="repository-hosting"]:checked', internal: true } + - id: select-workflow-capability + title: Enable workflow execution independently + action: + click: + css: 'input[name="capabilities"][value="workflow-execution"]' + internal: true + expect: + visible: + - { css: 'input[name="capabilities"][value="workflow-execution"]:checked', internal: true } + - id: connect-service + title: Persist provider metadata through the UI + action: + click: { role: button, name: Connect service } + expect: + urlIncludes: /app/services + text: Guarantee GitHub {{runShort}} {{deviceId}} + - id: open-service + title: Open the run-owned service + action: + click: { text: "Guarantee GitHub {{runShort}} {{deviceId}}" } + expect: + visible: + - { css: '[data-scene="service.detail"]', internal: true } + - id: open-credentials + title: Open the protected credentials tab + action: + click: { role: tab, name: Credentials } + expect: + visible: + - { css: '[data-scene="service.credential.github-app.privateKey"]', internal: true } + - id: enter-provider-credential + title: Enter a run-only provider credential into the local encryption form + action: + fill: + css: '[data-scene="service.credential.github-app.privateKey"] input[name="credentialValue"]' + internal: true + value: github-app-test-{{runShort}}-{{deviceId}} + expect: + visible: + - { css: '[data-scene="service.credential.github-app.privateKey"]', internal: true } + - id: unlock-team-vault + title: Unlock the administrator key locally + action: + fill: + css: '[data-scene="service.credential.github-app.privateKey"] input[name="passphrase"]' + internal: true + value: RotatedVault-{{runShort}}-{{deviceId}}! + expect: + visible: + - { css: '[data-scene="service.credential.github-app.privateKey"] button[type="submit"]', internal: true } + - id: encrypt-provider-credential + title: Encrypt and persist only a context-bound envelope + action: + click: { css: '[data-scene="service.credential.github-app.privateKey"] button[type="submit"]', internal: true } + expect: + urlIncludes: /app/services/ + text: GitHub App authority saved securely. + - id: open-operation-authorization + title: Review the one-use read-only validation lease + action: + click: { css: '[data-scene="service.validation.github-app"] summary', internal: true } + expect: + text: Only these fields are decrypted in this browser + - id: unlock-validation-credential + title: Unlock only the required credential locally + action: + fill: + css: '[data-scene="service.validation.github-app"] input[name="passphrase"]' + internal: true + value: RotatedVault-{{runShort}}-{{deviceId}}! + expect: + visible: + - { css: '[data-scene="service.validation.github-app"] button[type="submit"]', internal: true } + - id: authorize-read-only-validation + title: Seal the credential to the runner-issued ephemeral key + action: + click: { css: '[data-scene="service.validation.github-app"] button[type="submit"]', internal: true } + expect: + text: Read-only provider validation authorized. + - id: open-settings + title: Open canonical service settings tab + action: + click: { role: tab, name: Settings } + expect: + visible: + - { role: button, name: Save settings } + - id: edit-service-name + title: Change non-sensitive connection metadata + action: + fill: + css: '#service-panel-settings input[name="displayName"]' + internal: true + value: Guarantee GitHub updated {{runShort}} {{deviceId}} + expect: + visible: + - { role: button, name: Save settings } + - id: save-service-settings + title: Save the optimistic-versioned update without navigation + action: + click: { role: button, name: Save settings } + expect: + visible: + - { text: Service settings updated. } + - id: disconnect-service + title: Disconnect through the deliberate danger-zone control + action: + click: { role: button, name: Disconnect service } + expect: + urlIncludes: /app/services + notText: Guarantee GitHub updated {{runShort}} {{deviceId}} +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/service/connection/service-management-production-readiness.guarantee.yaml b/guarantees/service/connection/service-management-production-readiness.guarantee.yaml new file mode 100644 index 00000000..05398434 --- /dev/null +++ b/guarantees/service/connection/service-management-production-readiness.guarantee.yaml @@ -0,0 +1,52 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.service.connection.service-management-production-readiness.026 +type: service +subtype: connection +journey: Service Management Production Readiness +ownerPackage: "@treeseed/admin" +surface: scene +summary: Fail-closed aggregate for every service route, client custody contract, permission boundary, real device, durable postcondition, audit event, and cleanup requirement. +status: blocked +dependencies: + journeys: [21, 22, 23, 24, 25] + guarantees: + - guarantee.service.vault.initialize-personal-vault.021 + - guarantee.service.vault.recover-vault-access.022 + - guarantee.service.connection.connect-service.023 + - guarantee.service.connection.edit-service.024 + - guarantee.service.connection.disconnect-service.025 +actors: + allowed: [release_operator] + forbidden: [] +devices: + required: [desktop_chromium, tablet_chromium, mobile_chromium] +gates: [security, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: + - Every required service feature guarantee must pass against the same current source closure. +uiFeature: + contract: ../service-management.ui-feature.yaml + capabilities: [] +api: + required: true + verifierRefs: [sdk.service.vault.crypto, sdk.scene.secret-evidence-redaction, api.service.management.contracts, admin.service.ui-contracts] +content: + required: false + verifierRefs: [] +audit: + required: false + verifierRefs: [] +negativeCases: + - id: plaintext-or-context-substitution-denied + verifierRefs: [sdk.service.vault.crypto, sdk.scene.secret-evidence-redaction, api.service.management.contracts] + notes: + - Plaintext persistence, cross-context ciphertext, replay, or missing vault grants fail closed. +evidence: + required: [execution_graph, api_verification_log, cleanup_report] +notes: + - Blocked while journeys 23-25 and remote-provider management lack current-source real-provider scene evidence. + - Provider mutation and deployment guarantees remain blocked and cannot be satisfied by connection metadata. +run: + timeoutSeconds: 900 + requiredForRelease: true diff --git a/guarantees/service/scenes/negative/anonymous-services.scene.yaml b/guarantees/service/scenes/negative/anonymous-services.scene.yaml new file mode 100644 index 00000000..a45417fe --- /dev/null +++ b/guarantees/service/scenes/negative/anonymous-services.scene.yaml @@ -0,0 +1,54 @@ +schemaVersion: treeseed.scene/v1 +id: service.negative.anonymous-services +title: Anonymous Service Administration Denial +description: Anonymous visitors cannot reach service collection, connection, credential, or vault controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.navigation, service.connect, service.edit, service.credentials, service.disconnect, service.vault, service.vault-recovery] + minimumSteps: 3 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: anonymous, required: false } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: deny-service-collection + title: Redirect anonymous collection access + action: { goto: /app/services } + expect: { urlIncludes: "/auth/sign-in?returnTo=", text: Sign in } + - id: exercise-auth-boundary + title: Keep access at the sign-in boundary + action: { click: { role: button, name: Sign in } } + expect: + urlIncludes: "/auth/sign-in?returnTo=" + notVisible: [{ role: link, name: Add connection }] + - id: deny-vault + title: Redirect anonymous vault access + action: { goto: /app/services/vault } + expect: + urlIncludes: "/auth/sign-in?returnTo=" + notVisible: [{ role: button, name: Initialize team vault }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/service/scenes/negative/nonmember-services.scene.yaml b/guarantees/service/scenes/negative/nonmember-services.scene.yaml new file mode 100644 index 00000000..b5ab55cd --- /dev/null +++ b/guarantees/service/scenes/negative/nonmember-services.scene.yaml @@ -0,0 +1,61 @@ +schemaVersion: treeseed.scene/v1 +id: service.negative.nonmember-services +title: Nonmember Service Isolation +description: An authenticated nonmember cannot select another team's services or render its mutation controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.navigation, service.connect, service.edit, service.credentials, service.disconnect, service.vault, service.vault-recovery] + minimumSteps: 2 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: nonmember, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: isolate-service-collection + title: Open service availability without inferring an inaccessible team + action: { goto: /app/services } + expect: + urlIncludes: /app/services + text: Select an active team + notVisible: [{ role: link, name: Add connection }] + - id: isolate-service-vault + title: Do not expose another team's vault + action: { goto: /app/services/vault } + expect: + text: Select an active team + notVisible: [{ role: button, name: Initialize team vault }] + - id: exercise-empty-team-boundary + title: Use the visible team-management action without exposing another team + action: + clickVisibleSequence: + - { role: button, name: Open team operations } + - { css: '.ts-product-shell__desktop-operations a[aria-label="Manage teams"]', internal: true } + - { css: '#team-operations-drawer a[aria-label="Manage teams"]', internal: true } + expect: + urlIncludes: /app/teams + text: No teams yet +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/service/scenes/negative/readonly-services.scene.yaml b/guarantees/service/scenes/negative/readonly-services.scene.yaml new file mode 100644 index 00000000..6d319c9a --- /dev/null +++ b/guarantees/service/scenes/negative/readonly-services.scene.yaml @@ -0,0 +1,65 @@ +schemaVersion: treeseed.scene/v1 +id: service.negative.readonly-services +title: Read-only Team Member Service Controls +description: Contributors and viewers can inspect service availability but cannot connect, edit, or disconnect providers. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.connect, service.edit, service.disconnect, service.vault, service.vault-recovery] + minimumSteps: 3 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: member, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-team-collection + title: Open the accessible team collection + action: { goto: /app/teams } + expect: { visible: [{ css: ':nth-match([data-scene="team.active.set"], 1)', internal: true }] } + - id: select-team-context + title: Select the team through the visible active-team control + action: { click: { css: ':nth-match([data-scene="team.active.set"] button, 1)', internal: true } } + expect: { visible: [{ css: '[data-active="true"]', internal: true }] } + - id: view-availability-without-mutation + title: Open the scoped collection without connection controls + action: { goto: /app/services } + expect: + urlIncludes: /app/services + visible: [{ scene: service.collection }] + notVisible: [{ role: link, name: Add connection }] + - id: deny-provider-connection + title: Render a deliberate access explanation + action: { goto: /app/services/new } + expect: + text: Service administration required + notVisible: [{ scene: service.create.submit }] + - id: deny-vault-lifecycle + title: Omit team vault grant and lifecycle controls + action: { goto: /app/services/vault } + expect: + text: Only a team owner can initialize or change vault grants. + notVisible: [{ scene: service.vault.team.initialize }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/service/scenes/negative/vault-administrator-denial.scene.yaml b/guarantees/service/scenes/negative/vault-administrator-denial.scene.yaml new file mode 100644 index 00000000..187e7c66 --- /dev/null +++ b/guarantees/service/scenes/negative/vault-administrator-denial.scene.yaml @@ -0,0 +1,62 @@ +schemaVersion: treeseed.scene/v1 +id: service.negative.vault-administrator-denial +title: Ungranted Administrator Vault Denial +description: Non-owner service administrators and project leads cannot manage team vault grants or lifecycle without explicit ownership and cryptographic access. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.credentials, service.vault, service.vault-recovery] + minimumSteps: 2 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: service_admin, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-team-collection + title: Open the administrator team collection + action: { goto: /app/teams } + expect: { visible: [{ css: ':nth-match([data-scene="team.active.set"], 1)', internal: true }] } + - id: select-team-context + title: Select the team through the visible active-team control + action: { click: { css: ':nth-match([data-scene="team.active.set"] button, 1)', internal: true } } + expect: { visible: [{ css: '[data-active="true"]', internal: true }] } + - id: open-service-collection + title: Open the service collection through the administrator navigation + action: { goto: /app/services } + expect: { visible: [{ role: link, name: Add connection }] } + - id: open-service-wizard + title: Exercise the permitted non-secret service administration control + action: { click: { role: link, name: Add connection } } + expect: + urlIncludes: /app/services/new + visible: [{ scene: service.create }] + - id: explain-owner-boundary + title: Explain the separate team-owner and cryptographic grant boundary + action: { goto: /app/services/vault } + expect: + text: Only a team owner can initialize or change vault grants. + notVisible: [{ role: button, name: Initialize team vault }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/service/scenes/negative/vault-project-lead-denial.scene.yaml b/guarantees/service/scenes/negative/vault-project-lead-denial.scene.yaml new file mode 100644 index 00000000..760b8925 --- /dev/null +++ b/guarantees/service/scenes/negative/vault-project-lead-denial.scene.yaml @@ -0,0 +1,62 @@ +schemaVersion: treeseed.scene/v1 +id: service.negative.vault-project-lead-denial +title: Project Lead Vault Lifecycle Denial +description: A project lead can manage non-secret service metadata but cannot manage team vault grants or lifecycle. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.vault, service.vault-recovery] + minimumSteps: 2 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: admin, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-team-collection + title: Open the project-lead team collection + action: { goto: /app/teams } + expect: { visible: [{ css: ':nth-match([data-scene="team.active.set"], 1)', internal: true }] } + - id: select-team-context + title: Select the team through the visible active-team control + action: { click: { css: ':nth-match([data-scene="team.active.set"] button, 1)', internal: true } } + expect: { visible: [{ css: '[data-active="true"]', internal: true }] } + - id: open-service-collection + title: Open the service collection through the project-lead navigation + action: { goto: /app/services } + expect: { visible: [{ role: link, name: Add connection }] } + - id: exercise-service-metadata-role + title: Exercise the permitted provider connection control + action: { click: { role: link, name: Add connection } } + expect: + urlIncludes: /app/services/new + visible: [{ scene: service.create }] + - id: deny-vault-lifecycle + title: Omit team vault lifecycle controls + action: { goto: /app/services/vault } + expect: + text: Only a team owner can initialize or change vault grants. + notVisible: [{ role: button, name: Initialize team vault }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/service/scenes/negative/viewer-services.scene.yaml b/guarantees/service/scenes/negative/viewer-services.scene.yaml new file mode 100644 index 00000000..51f8daa8 --- /dev/null +++ b/guarantees/service/scenes/negative/viewer-services.scene.yaml @@ -0,0 +1,65 @@ +schemaVersion: treeseed.scene/v1 +id: service.negative.viewer-services +title: Viewer Service Controls +description: A viewer can inspect service availability but cannot connect or mutate provider services. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.connect, service.edit, service.disconnect, service.vault, service.vault-recovery] + minimumSteps: 3 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: viewer, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-team-collection + title: Open the accessible team collection + action: { goto: /app/teams } + expect: { visible: [{ css: ':nth-match([data-scene="team.active.set"], 1)', internal: true }] } + - id: select-team-context + title: Select the team through the visible active-team control + action: { click: { css: ':nth-match([data-scene="team.active.set"] button, 1)', internal: true } } + expect: { visible: [{ css: '[data-active="true"]', internal: true }] } + - id: view-scoped-services + title: Open service availability without mutation controls + action: { goto: /app/services } + expect: + urlIncludes: /app/services + visible: [{ scene: service.collection }] + notVisible: [{ role: link, name: Add connection }] + - id: deny-viewer-connection + title: Explain the administration boundary + action: { goto: /app/services/new } + expect: + text: Service administration required + notVisible: [{ scene: service.create.submit }] + - id: deny-viewer-vault-lifecycle + title: Omit team vault grant and lifecycle controls + action: { goto: /app/services/vault } + expect: + text: Only a team owner can initialize or change vault grants. + notVisible: [{ scene: service.vault.team.initialize }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 180, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/service/service-management.ui-feature.yaml b/guarantees/service/service-management.ui-feature.yaml new file mode 100644 index 00000000..2bb6f0e5 --- /dev/null +++ b/guarantees/service/service-management.ui-feature.yaml @@ -0,0 +1,87 @@ +schemaVersion: treeseed.ui-feature/v1 +id: admin.service-management +ownerPackage: "@treeseed/admin" +routes: + - /app/services + - /app/services/new + - /app/services/[connectionId] + - /app/services/vault +devices: [desktop_chromium, tablet_chromium, mobile_chromium] +states: [loading, empty, unavailable, forbidden, validation, conflict, success, reentry-required, destructive] +capabilities: + - id: service.navigation + routes: ["/app/services", "/app/services/new", "/app/services/[connectionId]", "/app/services/vault"] + actions: [open-services, scope-to-active-team, use-canonical-routed-tabs] + states: [empty, success, unavailable, forbidden] + actors: + allowed: [team_member] + forbidden: [anonymous_user, non_member] + guaranteeIds: [guarantee.service.connection.connect-service.023] + - id: service.vault + routes: [/app/services/vault] + actions: [review-custody-boundaries, follow-guided-setup, initialize-personal-key, initialize-team-vault, grant-access, revoke-access] + states: [validation, success, forbidden] + actors: + allowed: [team_owner] + forbidden: [project_lead, contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.service.vault.initialize-personal-vault.021] + - id: service.vault-recovery + routes: [/app/services/vault] + actions: [rotate-personal-passphrase, recover-by-grant, reset-vault] + states: [validation, success, destructive, forbidden] + actors: + allowed: [team_owner] + forbidden: [service_admin, project_lead, contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.service.vault.recover-vault-access.022] + - id: service.connect + routes: [/app/services/new] + actions: [choose-provider, inspect-help, select-capabilities, validate, connect] + states: [validation, conflict, success, unavailable, forbidden] + actors: + allowed: [team_owner, project_lead, service_admin] + forbidden: [contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.service.connection.connect-service.023] + - id: service.credentials + routes: ["/app/services/[connectionId]"] + actions: [encrypt-field, save-envelope, inspect-custody, authorize-operation] + states: [validation, success, reentry-required, forbidden] + actors: + allowed: [credential_grantee] + forbidden: [ungranted_service_admin, contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.service.connection.edit-service.024] + - id: service.edit + routes: ["/app/services/[connectionId]"] + actions: [edit-metadata, change-capabilities, persist-conflict-safe] + states: [validation, conflict, success, unavailable, forbidden] + actors: + allowed: [team_owner, project_lead, service_admin] + forbidden: [contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.service.connection.edit-service.024] + - id: service.disconnect + routes: ["/app/services/[connectionId]"] + actions: [inspect-dependencies, disconnect, clean-ciphertext] + states: [blocked, destructive, success, forbidden] + actors: + allowed: [team_owner, project_lead, service_admin] + forbidden: [contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.service.connection.disconnect-service.025] + - id: service.contextual-help + routes: ["/app/services", "/app/services/new", "/app/services/[connectionId]", "/app/services/vault"] + actions: [open-route-help, open-section-help, navigate-related-topics, search-authorized-topics, close-and-restore-focus] + states: [loading, success, unavailable, forbidden] + actors: + allowed: [team_member, credential_grantee] + forbidden: [anonymous_user, non_member] + guaranteeIds: + - guarantee.service.vault.initialize-personal-vault.021 + - guarantee.service.vault.recover-vault-access.022 +requiredGuarantees: + - guarantee.service.vault.initialize-personal-vault.021 + - guarantee.service.vault.recover-vault-access.022 +requirements: + accessibility: true + console: true + network: true + visual: true + durableState: true + cleanup: true diff --git a/guarantees/service/vault/initialize-personal-vault.guarantee.yaml b/guarantees/service/vault/initialize-personal-vault.guarantee.yaml new file mode 100644 index 00000000..3573d584 --- /dev/null +++ b/guarantees/service/vault/initialize-personal-vault.guarantee.yaml @@ -0,0 +1,51 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.service.vault.initialize-personal-vault.021 +journeyIndex: 21 +type: service +subtype: vault +journey: Create Passphrase +ownerPackage: "@treeseed/admin" +summary: Initialize personal client-side vault access and the active team's encrypted credential vault. +status: active +dependencies: + journeys: [4, 13] + guarantees: [guarantee.user.auth.user-login.004, guarantee.team.team.switch-active-team.013] +actors: + allowed: [team_owner] + forbidden: [anonymous_user, non_member, contributor, viewer] +devices: + required: [desktop_chromium, tablet_chromium, mobile_chromium] +gates: [security, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [An authenticated owner has selected an active team.] +uiFeature: + contract: ../service-management.ui-feature.yaml + capabilities: [service.vault, service.contextual-help] +scene: + required: true + manifest: ./scenes/vault-lifecycle.scene.yaml + executionKey: admin.services.vault-lifecycle + entryRoute: /app/services/vault + componentContract: client-encrypted vault service journey + expectedEvidence: [playwright_trace, scene_video, screenshot_on_failure, console_log, network_log] +api: + required: true + verifierRefs: [api.service.management.contracts, sdk.service.vault.crypto] +content: + required: false + verifierRefs: [] +audit: + required: true + verifierRefs: [api.service.management.contracts] +negativeCases: + - { id: anonymous-denied, actor: anonymous_user, sceneManifest: ../scenes/negative/anonymous-services.scene.yaml, executionKey: admin.services.negative.anonymous, verifierRefs: [api.service.management.contracts] } + - { id: nonmember-denied, actor: non_member, sceneManifest: ../scenes/negative/nonmember-services.scene.yaml, executionKey: admin.services.negative.nonmember, verifierRefs: [api.service.management.contracts] } + - { id: contributor-denied, actor: contributor, sceneManifest: ../scenes/negative/readonly-services.scene.yaml, executionKey: admin.services.negative.contributor, verifierRefs: [api.service.management.contracts] } + - { id: viewer-denied, actor: viewer, sceneManifest: ../scenes/negative/viewer-services.scene.yaml, executionKey: admin.services.negative.viewer, verifierRefs: [api.service.management.contracts] } +evidence: + required: [playwright_trace, scene_video, api_verification_log] +surface: admin-ui +run: + timeoutSeconds: 300 + requiredForRelease: true diff --git a/guarantees/service/vault/recover-vault-access.guarantee.yaml b/guarantees/service/vault/recover-vault-access.guarantee.yaml new file mode 100644 index 00000000..5e4783d4 --- /dev/null +++ b/guarantees/service/vault/recover-vault-access.guarantee.yaml @@ -0,0 +1,53 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.service.vault.recover-vault-access.022 +journeyIndex: 22 +type: service +subtype: vault +journey: Reset Passphrase +ownerPackage: "@treeseed/admin" +summary: Rotate a personal passphrase without rewriting credentials and perform the explicit unrecoverable vault-reset ceremony. +status: active +dependencies: + journeys: [21] + guarantees: [guarantee.service.vault.initialize-personal-vault.021] +actors: + allowed: [team_owner] + forbidden: [anonymous_user, non_member, project_lead, service_admin, contributor, viewer] +devices: + required: [desktop_chromium, tablet_chromium, mobile_chromium] +gates: [security, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [Personal and team vault access has been initialized.] +uiFeature: + contract: ../service-management.ui-feature.yaml + capabilities: [service.vault-recovery, service.contextual-help] +scene: + required: true + manifest: ./scenes/vault-lifecycle.scene.yaml + executionKey: admin.services.vault-lifecycle + entryRoute: /app/services/vault + componentContract: destructive vault recovery service journey + expectedEvidence: [playwright_trace, scene_video, screenshot_on_failure, console_log, network_log] +api: + required: true + verifierRefs: [api.service.management.contracts, sdk.service.vault.crypto] +content: + required: false + verifierRefs: [] +audit: + required: true + verifierRefs: [api.service.management.contracts] +negativeCases: + - { id: anonymous-denied, actor: anonymous_user, sceneManifest: ../scenes/negative/anonymous-services.scene.yaml, executionKey: admin.services.negative.anonymous, verifierRefs: [api.service.management.contracts] } + - { id: nonmember-denied, actor: non_member, sceneManifest: ../scenes/negative/nonmember-services.scene.yaml, executionKey: admin.services.negative.nonmember, verifierRefs: [api.service.management.contracts] } + - { id: project-lead-denied, actor: project_lead, sceneManifest: ../scenes/negative/vault-project-lead-denial.scene.yaml, executionKey: admin.services.negative.project-lead, verifierRefs: [api.service.management.contracts] } + - { id: service-admin-denied, actor: service_admin, sceneManifest: ../scenes/negative/vault-administrator-denial.scene.yaml, executionKey: admin.services.negative.service-admin, verifierRefs: [api.service.management.contracts] } + - { id: contributor-denied, actor: contributor, sceneManifest: ../scenes/negative/readonly-services.scene.yaml, executionKey: admin.services.negative.contributor, verifierRefs: [api.service.management.contracts] } + - { id: viewer-denied, actor: viewer, sceneManifest: ../scenes/negative/viewer-services.scene.yaml, executionKey: admin.services.negative.viewer, verifierRefs: [api.service.management.contracts] } +evidence: + required: [playwright_trace, scene_video, api_verification_log] +surface: admin-ui +run: + timeoutSeconds: 300 + requiredForRelease: true diff --git a/guarantees/service/vault/scenes/vault-lifecycle.scene.yaml b/guarantees/service/vault/scenes/vault-lifecycle.scene.yaml new file mode 100644 index 00000000..4e0a2e09 --- /dev/null +++ b/guarantees/service/vault/scenes/vault-lifecycle.scene.yaml @@ -0,0 +1,297 @@ +schemaVersion: treeseed.scene/v1 +id: service.vault.vault-lifecycle.021-022 +title: Initialize and rotate service vault access +description: Creates personal and team vault access through rendered controls, rotates the personal passphrase, and proves the page remains usable. +audience: [operator, evaluator] +journey: + kind: service + proves: [service.vault, service.vault-recovery, service.contextual-help] + minimumSteps: 24 + requiresInteractiveAction: true + consumesState: + - key: team.active-session + kind: browser-storage + - key: team.primary + kind: marker + producesState: + - key: services.team-vault + kind: marker + value: + status: active + custody: client-encrypted-vault +mode: + test: true + demo: true + training: true +target: + app: market + environment: local + baseUrl: auto + browser: chromium +devices: + defaultProfile: desktop_chromium + profiles: + - id: desktop_chromium + title: Desktop Chromium + viewport: { width: 1600, height: 900 } + video: { width: 1600, height: 900 } + output: { width: 1920, height: 1080 } + deviceScaleFactor: 1 + isMobile: false + hasTouch: false + - id: tablet_chromium + title: Tablet Chromium + viewport: { width: 820, height: 1180 } + video: { width: 820, height: 1180 } + output: { width: 820, height: 1180 } + deviceScaleFactor: 2 + isMobile: true + hasTouch: true + - id: mobile_chromium + title: Mobile Chromium + viewport: { width: 390, height: 844 } + video: { width: 390, height: 844 } + output: { width: 390, height: 844 } + deviceScaleFactor: 2 + isMobile: true + hasTouch: true +setup: + dev: { required: true, reuseExisting: true } + auth: { role: owner, required: true } +artifacts: + trace: true + video: true + screenshots: true + console: true + network: true + timeline: true + appLogs: true +workflow: + - id: open-vault + title: Open service vault + action: { goto: /app/services/vault } + expect: + urlIncludes: /app/services/vault + visible: + - { css: '[data-scene="service.vault"]', internal: true } + - { css: '[data-scene="service.vault.personal.initialize"]', internal: true } + text: Credentials stay under your control + - id: open-personal-key-help + title: Open the personal administrator key guidance + action: + click: { css: '.ts-setup-progress button[data-ts-help-knowledge-page-id="vault.personal-key"]', internal: true } + expect: + visible: + - { css: '[data-ts-help-dialog][open]', internal: true } + text: Step 1 creates a public/private encryption keypair in your browser. + - id: close-personal-key-help + title: Close personal key guidance and restore focus + action: + click: { role: button, name: Close help } + expect: + notVisible: + - { css: '[data-ts-help-dialog][open]', internal: true } + focused: { css: '.ts-setup-progress button[data-ts-help-knowledge-page-id="vault.personal-key"]', internal: true } + - id: open-team-custody-help + title: Open team credential custody guidance + action: + click: { css: '.ts-setup-progress button[data-ts-help-knowledge-page-id="vault.team-custody"]', internal: true } + expect: + visible: + - { css: '[data-ts-help-dialog][open]', internal: true } + text: Enter the same personal vault passphrase you created in step 1. + - id: close-team-custody-help + title: Close team custody guidance and restore focus + action: + click: { role: button, name: Close help } + expect: + notVisible: + - { css: '[data-ts-help-dialog][open]', internal: true } + focused: { css: '.ts-setup-progress button[data-ts-help-knowledge-page-id="vault.team-custody"]', internal: true } + - id: open-recovery-help + title: Open recovery and administrator grant guidance + action: + click: { css: '.ts-setup-progress button[data-ts-help-knowledge-page-id="vault.recovery"]', internal: true } + expect: + visible: + - { css: '[data-ts-help-dialog][open]', internal: true } + text: Another currently authorized credential administrator can grant a replacement personal key access after you forget your passphrase. + - id: close-recovery-help + title: Close recovery guidance and restore focus + action: + click: { role: button, name: Close help } + expect: + notVisible: + - { css: '[data-ts-help-dialog][open]', internal: true } + focused: { css: '.ts-setup-progress button[data-ts-help-knowledge-page-id="vault.recovery"]', internal: true } + - id: enter-personal-passphrase + title: Enter a personal passphrase and confirmation + action: + fill: + css: '[data-scene="service.vault.personal.initialize"] input[name="passphrase"]' + internal: true + value: VaultGuarantee-{{runShort}}-{{deviceId}}! + expect: + visible: + - { css: '[data-scene="service.vault.personal.initialize"]', internal: true } + - id: confirm-personal-passphrase + title: Confirm the personal passphrase + action: + fill: + css: '[data-scene="service.vault.personal.initialize"] input[name="confirmPassphrase"]' + internal: true + value: VaultGuarantee-{{runShort}}-{{deviceId}}! + expect: + visible: + - { role: button, name: Create personal vault key } + - id: create-personal-key + title: Create the browser-encrypted administrator key + action: + click: { role: button, name: Create personal vault key } + expect: + urlIncludes: /app/services/vault + text: Administrator key ready + - id: enter-team-vault-passphrase + title: Unlock the administrator key for team initialization + action: + fill: + css: '[data-scene="service.vault.team.initialize"] input[name="passphrase"]' + internal: true + value: VaultGuarantee-{{runShort}}-{{deviceId}}! + expect: + visible: + - { role: button, name: Initialize team vault } + - id: initialize-team-vault + title: Create and wrap a random team vault key + action: + click: { role: button, name: Initialize team vault } + expect: + urlIncludes: /app/services/vault + text: Team vault active + - id: open-passphrase-rotation + title: Open personal passphrase rotation + action: + click: { text: Change personal passphrase } + expect: + text: Provider credentials are not decrypted or rewritten. + - id: fill-current-passphrase + title: Unlock the existing personal key locally + action: + fill: + css: 'form[data-ts-form-adapter="personal-vault-rotate"] input[name="currentPassphrase"]' + internal: true + value: VaultGuarantee-{{runShort}}-{{deviceId}}! + expect: + visible: + - { css: 'form[data-ts-form-adapter="personal-vault-rotate"]', internal: true } + - id: fill-new-passphrase + title: Enter and confirm the replacement passphrase + action: + fill: + css: 'form[data-ts-form-adapter="personal-vault-rotate"] input[name="passphrase"]' + internal: true + value: RotatedVault-{{runShort}}-{{deviceId}}! + expect: + visible: + - { role: button, name: Change passphrase } + - id: confirm-new-passphrase + title: Confirm the replacement passphrase + action: + fill: + css: 'form[data-ts-form-adapter="personal-vault-rotate"] input[name="confirmPassphrase"]' + internal: true + value: RotatedVault-{{runShort}}-{{deviceId}}! + expect: + visible: + - { role: button, name: Change passphrase } + - id: rotate-personal-passphrase + title: Re-encrypt only the personal private-key envelope + action: + click: { role: button, name: Change passphrase } + expect: + urlIncludes: /app/services/vault + text: Personal vault passphrase changed. + - id: reload-after-personal-rotation + title: Reload persisted vault state before team-key rotation + action: { goto: /app/services/vault } + expect: + text: Team vault active + - id: open-team-key-rotation + title: Open the team vault key rotation ceremony + action: + click: { text: Rotate the team vault key } + expect: + text: Rewrap every credential key and administrator grant + - id: unlock-team-key-rotation + title: Unlock the current team key locally + action: + fill: + css: '[data-scene="service.vault.rotate"] input[name="passphrase"]' + internal: true + value: RotatedVault-{{runShort}}-{{deviceId}}! + expect: + visible: + - { role: button, name: Rotate team vault key } + - id: rotate-team-key + title: Rewrap the active administrator grants without credential plaintext + action: + click: { role: button, name: Rotate team vault key } + expect: + text: Team vault key rotated. + - id: reload-after-team-rotation + title: Load the replacement team vault grant + action: { goto: /app/services/vault } + expect: + visible: + - { css: '[data-scene="service.vault.reset"]', internal: true } + - id: unlock-vault-reset + title: Unlock the administrator key for unrecoverable reset + action: + fill: + css: '[data-scene="service.vault.reset"] input[name="passphrase"]' + internal: true + value: RotatedVault-{{runShort}}-{{deviceId}}! + expect: + visible: + - { role: button, name: Reset vault and discard credentials } + - id: confirm-vault-reset + title: Enter the exact destructive vault reset confirmation + action: + fill: + css: '[data-scene="service.vault.reset"] input[name="confirmation"]' + internal: true + value: RESET gt-{{runShort}}-{{deviceId}} + expect: + visible: + - { css: '[data-scene="service.vault.reset"] input[name="currentPassword"]', internal: true } + - id: reauthenticate-vault-reset + title: Reauthenticate the owner for destructive recovery + action: + fill: + css: '[data-scene="service.vault.reset"] input[name="currentPassword"]' + internal: true + value: TreeSeedGuaranteeReset123! + expect: + visible: + - { role: button, name: Reset vault and discard credentials } + - id: reset-unrecoverable-vault + title: Replace the inaccessible team vault and require credential reentry + action: + click: { role: button, name: Reset vault and discard credentials } + expect: + text: Vault reset. Reenter every protected provider credential. +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/audit/scenes/view-team-audit-log.scene.yaml b/guarantees/team/audit/scenes/view-team-audit-log.scene.yaml deleted file mode 100644 index ebe299a3..00000000 --- a/guarantees/team/audit/scenes/view-team-audit-log.scene.yaml +++ /dev/null @@ -1,130 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team.audit.view-team-audit-log.093 -title: View Team Audit Log -description: Acceptance scene for guarantee.team.audit.view-team-audit-log.093. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - View Team Audit Log opens the canonical @treeseed/admin record operations workflow. - - View Team Audit Log exercises a service journey instead of only loading /app/teams. - - View Team Audit Log records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open View Team Audit Log - action: - goto: /app/teams - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect View Team Audit Log service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/team/audit/view-team-audit-log.guarantee.yaml b/guarantees/team/audit/view-team-audit-log.guarantee.yaml deleted file mode 100644 index 775af3d1..00000000 --- a/guarantees/team/audit/view-team-audit-log.guarantee.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.team.audit.view-team-audit-log.093 -journeyIndex: 93 -type: team -subtype: audit -journey: View Team Audit Log -ownerPackage: "@treeseed/admin" -summary: Show membership project capacity host secret and workday changes for accountability across admin/API operations. -status: active -dependencies: - journeys: - - 12 - guarantees: - - guarantee.team.team.create-team.012 -actors: - allowed: - - team_admin - - team_owner - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - - "Journey dependencies must be satisfied: 12" -scene: - required: true - manifest: ./scenes/view-team-audit-log.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - api.team.permissions.owner -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] -negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - optional: - - mailpit_message -notes: - - Show membership project capacity host secret and workday changes for accountability across admin/API operations. -surface: admin-ui -run: - timeoutSeconds: 300 - requiredForRelease: true diff --git a/guarantees/team/membership/accept-team-invitation.guarantee.yaml b/guarantees/team/membership/accept-team-invitation.guarantee.yaml index baba25ff..c640cbc8 100644 --- a/guarantees/team/membership/accept-team-invitation.guarantee.yaml +++ b/guarantees/team/membership/accept-team-invitation.guarantee.yaml @@ -14,11 +14,9 @@ dependencies: - guarantee.team.membership.invite-team-members.017 actors: allowed: - - team_admin - - team_owner + - invited_user forbidden: - - anonymous_user - - unauthorized_user + - mismatched_user devices: required: - desktop_chromium @@ -30,16 +28,19 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - "Journey dependencies must be satisfied: 17" +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.invitation-consent] scene: required: true manifest: ./scenes/accept-team-invitation.scene.yaml + executionKey: admin.team.accept-invite mode: acceptance: true demo: true training: true - entryRoute: /app/teams/visual-audit-team/members + entryRoute: /team-invites/[token]/accept componentContract: redirect/session service journey expectedEvidence: - playwright_trace @@ -50,18 +51,21 @@ scene: api: required: true verifierRefs: - - api.team.invite.mailpit + - api.team.accept.correlated content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.team.accept.correlated] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: mismatched-user-denied + actor: mismatched_user + sceneManifest: scenes/invitation-mismatched-user.scene.yaml + executionKey: admin.team.invitation.mismatched-user + verifierRefs: [api.team.invitation.mismatch-denied] + - id: invalid-expired-revoked-replay + verifierRefs: [api.team.invitation.terminal-states] evidence: required: - playwright_trace diff --git a/guarantees/team/membership/change-member-role.guarantee.yaml b/guarantees/team/membership/change-member-role.guarantee.yaml index a5736a91..15e50202 100644 --- a/guarantees/team/membership/change-member-role.guarantee.yaml +++ b/guarantees/team/membership/change-member-role.guarantee.yaml @@ -17,8 +17,7 @@ actors: - team_admin - team_owner forbidden: - - anonymous_user - - unauthorized_user + - contributor devices: required: - desktop_chromium @@ -30,16 +29,19 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - "Journey dependencies must be satisfied: 18" +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.member-roles, team.ownership] scene: required: true manifest: ./scenes/change-member-role.scene.yaml + executionKey: admin.team.change-member-role mode: acceptance: true demo: true training: true - entryRoute: /app/teams/visual-audit-team/members + entryRoute: /app/teams/[teamId]/members componentContract: record-modal-form service journey expectedEvidence: - playwright_trace @@ -50,18 +52,19 @@ scene: api: required: true verifierRefs: - - api.team.member.role + - api.team.role.correlated content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.team.role.correlated] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: contributor-denied + actor: contributor + sceneManifest: ../scenes/negative/members-contributor.scene.yaml + executionKey: admin.team.negative.members-contributor + verifierRefs: [api.team.role.contributor-denied] evidence: required: - playwright_trace diff --git a/guarantees/team/membership/invite-team-members.guarantee.yaml b/guarantees/team/membership/invite-team-members.guarantee.yaml index f69e0e4c..69dbd7d5 100644 --- a/guarantees/team/membership/invite-team-members.guarantee.yaml +++ b/guarantees/team/membership/invite-team-members.guarantee.yaml @@ -9,16 +9,15 @@ summary: Create team invitation records and send notices; roles should map to AP status: active dependencies: journeys: - - 12 + - 14 guarantees: - - guarantee.team.team.create-team.012 + - guarantee.team.team.edit-team-settings.014 actors: allowed: - team_admin - team_owner forbidden: - - anonymous_user - - unauthorized_user + - contributor devices: required: - desktop_chromium @@ -30,16 +29,19 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - "Journey dependencies must be satisfied: 12" +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.member-directory, team.invitations] scene: required: true manifest: ./scenes/invite-team-members.scene.yaml + executionKey: admin.team.invite mode: acceptance: true demo: true training: true - entryRoute: /app/teams/visual-audit-team/members + entryRoute: /app/teams/[teamId]/members componentContract: modal-form service journey expectedEvidence: - playwright_trace @@ -50,18 +52,19 @@ scene: api: required: true verifierRefs: - - api.team.invite.mailpit + - api.team.invite.correlated content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.team.invite.correlated] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: contributor-denied + actor: contributor + sceneManifest: ../scenes/negative/members-contributor.scene.yaml + executionKey: admin.team.negative.members-contributor + verifierRefs: [api.team.invite.contributor-denied] evidence: required: - playwright_trace diff --git a/guarantees/team/membership/remove-team-member.guarantee.yaml b/guarantees/team/membership/remove-team-member.guarantee.yaml index 3d39ffa6..48ab8837 100644 --- a/guarantees/team/membership/remove-team-member.guarantee.yaml +++ b/guarantees/team/membership/remove-team-member.guarantee.yaml @@ -9,16 +9,15 @@ summary: Remove or deactivate a team member with auditability; must avoid orphan status: active dependencies: journeys: - - 18 + - 19 guarantees: - - guarantee.team.membership.accept-team-invitation.018 + - guarantee.team.membership.change-member-role.019 actors: allowed: - team_admin - team_owner forbidden: - - anonymous_user - - unauthorized_user + - contributor devices: required: - desktop_chromium @@ -30,16 +29,19 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - "Journey dependencies must be satisfied: 18" +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.member-removal, team.member-leave] scene: required: true manifest: ./scenes/remove-team-member.scene.yaml + executionKey: admin.team.remove-member mode: acceptance: true demo: true training: true - entryRoute: /app/teams/visual-audit-team/members + entryRoute: /app/teams/[teamId]/members componentContract: record-action service journey expectedEvidence: - playwright_trace @@ -50,18 +52,19 @@ scene: api: required: true verifierRefs: - - api.team.member.remove + - api.team.remove.correlated content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.team.remove.correlated] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: contributor-denied + actor: contributor + sceneManifest: ../scenes/negative/members-contributor.scene.yaml + executionKey: admin.team.negative.members-contributor + verifierRefs: [api.team.remove.contributor-denied] evidence: required: - playwright_trace diff --git a/guarantees/team/membership/scenes/accept-team-invitation.scene.yaml b/guarantees/team/membership/scenes/accept-team-invitation.scene.yaml index 3e1c18ec..f015a501 100644 --- a/guarantees/team/membership/scenes/accept-team-invitation.scene.yaml +++ b/guarantees/team/membership/scenes/accept-team-invitation.scene.yaml @@ -8,14 +8,17 @@ audience: journey: kind: service proves: - - Accept Team Invitation opens the canonical @treeseed/admin dashboard read model workflow. - - Accept Team Invitation exercises a service journey instead of only loading /app/teams/visual-audit-team/members. - - Accept Team Invitation records reviewable evidence for the visible result before activation. - minimumSteps: 2 + - team.invitation-consent + minimumSteps: 17 requiresInteractiveAction: true consumesState: - - key: team.primary - kind: team + - key: team.invitation + kind: marker + producesState: + - key: team.membership-accepted + kind: marker + value: + recipient: invite-{{runId}}-{{deviceId}}@treeseed.local mode: test: true demo: true @@ -74,18 +77,189 @@ artifacts: timeline: true appLogs: true workflow: - - id: open-entry-route - title: Open Accept Team Invitation + - id: open-exact-invitation + title: Open the exact invitation from Mailpit action: - goto: /app/teams/visual-audit-team/members + mailpitConfirmLatest: + mailpitUrl: http://127.0.0.1:8025 + email: invite-{{runId}}-{{deviceId}}@treeseed.local + subjectIncludes: You're invited to join Verified {{runShort}} {{deviceId}} expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Accept Team Invitation service surface + urlIncludes: /team-invites/ + text: Team invitation + - id: open-invited-registration + title: Safely sign out while preserving the invitation token action: - keyboard: Tab + click: + role: button + name: Switch account expect: - urlIncludes: /app/teams + urlIncludes: /auth/sign-in + text: Sign in + - id: choose-invited-registration + title: Choose registration while preserving the invitation token + action: + click: + role: link + name: Create account + expect: + urlIncludes: /auth/register + text: Create account + - id: fill-invited-first-name + title: Set the invited user's first name + action: + fill: + role: textbox + name: First name + value: Invited + expect: + text: Create account + - id: fill-invited-last-name + title: Set the invited user's last name + action: + fill: + role: textbox + name: Last name + value: Member + expect: + text: Create account + - id: fill-invited-username + title: Set the invited user's username + action: + fill: + role: textbox + name: Username + value: i-{{runShort}}-{{deviceId}} + expect: + text: Create account + - id: fill-invited-password + title: Set the invited user's password + action: + fill: + css: '#registerPassword' + internal: true + value: TreeSeedInviteGuarantee123! + expect: + text: Create account + - id: confirm-invited-password + title: Confirm the invited user's password + action: + fill: + css: 'input[name="confirmPassword"]' + internal: true + value: TreeSeedInviteGuarantee123! + expect: + text: Create account + - id: submit-invited-registration + title: Register the invited principal without silently accepting membership + action: + click: + role: button + name: Create account + expect: + urlIncludes: /auth/check-email + text: Check your email + - id: confirm-invited-email + title: Confirm the invited user's email through Mailpit + action: + mailpitConfirmLatest: + mailpitUrl: http://127.0.0.1:8025 + email: invite-{{runId}}-{{deviceId}}@treeseed.local + subjectIncludes: Confirm your TreeSeed email + displayInboxSeconds: 1 + displayMessageSeconds: 1 + expect: + urlIncludes: /auth/confirm-email + text: Confirm your email + - id: submit-invited-email-confirmation + title: Explicitly consume the one-use email confirmation + action: + click: { role: button, name: Confirm email } + expect: + text: Email confirmed + - id: continue-invited-sign-in + title: Sign in with the preserved invitation return path + action: + click: { role: link, name: Sign in } + expect: + urlIncludes: /auth/sign-in + - id: fill-invited-authorization-identifier + title: Reauthenticate the invited account at the decision boundary + action: + fill: { role: textbox, name: Email or username, value: 'invite-{{runId}}-{{deviceId}}@treeseed.local' } + expect: + text: Sign in + - id: fill-invited-authorization-password + title: Enter the invited account password at the decision boundary + action: + fill: { css: 'input[name="password"]', internal: true, value: TreeSeedInviteGuarantee123! } + expect: + text: Sign in + - id: approve-invited-authorization + title: Sign in through the first-party Admin BFF + action: + click: { role: button, name: Sign in } + expect: + urlIncludes: /team-invites/ + text: Accept invitation + - id: explicitly-accept-invitation + title: Explicitly accept the invitation through the CSRF-protected form + action: + click: + role: button + name: Accept invitation + expect: + urlIncludes: /app/teams/ + text: Operational overview + visible: + - scene: app-shell + - id: open-existing-user-invitation + title: Open the existing verified user's exact invitation + action: + mailpitConfirmLatest: + mailpitUrl: http://127.0.0.1:8025 + email: visual.member@treeseed.io + subjectIncludes: You're invited to join Verified {{runShort}} {{deviceId}} + expect: + urlIncludes: /team-invites/ + text: Switch to the invited account before accepting. + - id: switch-to-existing-user + title: Use the safe POST account switch while preserving the invitation + action: + click: + role: button + name: Switch account + expect: + urlIncludes: /auth/sign-in + text: Sign in + - id: fill-existing-user-authorization-identifier + title: Reauthenticate the existing user at the decision boundary + action: + fill: { role: textbox, name: Email or username, value: visual.member@treeseed.io } + expect: + text: Sign in + - id: fill-existing-user-authorization-password + title: Enter the existing user's password at the decision boundary + action: + fill: { css: 'input[name="password"]', internal: true, value: TreeSeedVisualAudit!2026 } + expect: + text: Sign in + - id: approve-existing-user-authorization + title: Sign in to Admin and return to the preserved invitation + action: + click: { role: button, name: Sign in } + expect: + urlIncludes: /team-invites/ + text: Accept invitation + - id: explicitly-accept-as-existing-user + title: Accept explicitly as the existing verified user + action: + click: + role: button + name: Accept invitation + expect: + urlIncludes: /app/teams/ + text: Operational overview chapters: [] overlays: [] diagrams: [] @@ -122,4 +296,4 @@ runtime: continueOnFailure: false training: {} visualAudit: - enabled: false + enabled: true diff --git a/guarantees/team/membership/scenes/change-member-role.scene.yaml b/guarantees/team/membership/scenes/change-member-role.scene.yaml index d4e31fa2..84add8fd 100644 --- a/guarantees/team/membership/scenes/change-member-role.scene.yaml +++ b/guarantees/team/membership/scenes/change-member-role.scene.yaml @@ -8,16 +8,20 @@ audience: journey: kind: service proves: - - Change Member Role opens the canonical @treeseed/admin dashboard read model workflow. - - Change Member Role exercises a service journey instead of only loading /app/teams/visual-audit-team/members. - - Change Member Role records reviewable evidence for the visible result before activation. - minimumSteps: 2 + - team.member-roles + - team.ownership + minimumSteps: 18 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team + - key: auth.primary-session + kind: browser-storage + - key: team.membership-accepted + kind: marker + producesState: + - key: team.member-role-changed + kind: marker + - key: auth.primary-session-after-role + kind: browser-storage mode: test: true demo: true @@ -82,15 +86,251 @@ workflow: - id: open-entry-route title: Open Change Member Role action: - goto: /app/teams/visual-audit-team/members + goto: /app/teams expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Change Member Role service surface + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-members + title: Open members for the run-created team action: - keyboard: Tab + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true expect: - urlIncludes: /app/teams + text: invite-{{runId}}-{{deviceId}}@treeseed.local + visible: + - scene: team.navigation + - scene: team.roles.reference.open + - id: open-role-reference + title: Open the role responsibility reference + action: + click: + role: button + name: Open role reference + expect: + text: Roles and responsibilities + visible: + - css: '#team-role-reference[open] .ts-disclosure-list' + internal: true + - id: close-role-reference + title: Close the role responsibility reference + action: + click: + role: button + name: Close dialog + expect: + notVisible: + - css: '#team-role-reference[open]' + internal: true + - id: choose-reviewer-role + title: Change the invited member to reviewer + action: + select: + css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"] select[name="roleKey"]' + internal: true + value: reviewer + expect: + text: invite-{{runId}}-{{deviceId}}@treeseed.local + - id: save-member-role + title: Persist the member role + action: + click: + css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"] form[data-ts-method="PATCH"] button[type="submit"]' + internal: true + expect: + urlIncludes: /members + text: Member role updated. + visible: + - css: '[data-ts-toast-id][data-tone="success"]:last-of-type' + internal: true + - id: verify-member-role + title: Prove the reviewer role persisted after the refreshed member panel + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: reopen-members-after-role-change + title: Reopen members and prove the role persisted + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + visible: + - css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="reviewer"]' + internal: true + - scene: team.roles.reference.open + - id: transfer-ownership-to-invited-member + title: Transfer ownership through the visible owner-only control + action: + click: + css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"] form[data-scene="team.ownership.transfer"] button[type="submit"]' + internal: true + expect: + text: Ownership transferred. + visible: + - css: '[data-ts-toast-id][data-tone="success"]:last-of-type' + internal: true + - css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="team_owner"]' + internal: true + - css: '[data-member-email="guarantee-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="project_lead"]' + internal: true + - id: sign-out-former-owner + title: End the former owner's browser session before restoring ownership + action: + click: + role: button + name: Sign out + revealWith: { role: button, name: Open team operations } + expect: + urlIncludes: /auth/sign-in + text: Sign in + - id: enter-invited-owner-approval-email + title: Re-enter the invited owner's credential at the sign-in boundary + action: + fill: + role: textbox + name: Email or username + value: invite-{{runId}}-{{deviceId}}@treeseed.local + expect: + text: Sign in + - id: enter-invited-owner-approval-password + title: Enter the invited owner's password for explicit client approval + action: + fill: + css: 'input[name="password"]' + internal: true + value: TreeSeedInviteGuarantee123! + expect: + text: Sign in + - id: approve-invited-owner-session + title: Sign in to Admin as the invited owner + action: + click: + role: button + name: Sign in + expect: + urlIncludes: /app + visible: + - scene: app-shell + - id: open-team-as-invited-owner + title: Open the same run-created team as its current owner + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-members-as-invited-owner + title: Open ownership administration as the invited owner + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + visible: + - css: '[data-member-email="guarantee-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="project_lead"]' + internal: true + - id: restore-primary-ownership + title: Transfer ownership back through the same visible owner-only control + action: + click: + css: '[data-member-email="guarantee-{{runId}}-{{deviceId}}@treeseed.local"] form[data-scene="team.ownership.transfer"] button[type="submit"]' + internal: true + expect: + text: Ownership transferred. + visible: + - css: '[data-member-email="guarantee-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="team_owner"]' + internal: true + - css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="project_lead"]' + internal: true + - id: sign-out-invited-owner + title: End the invited user's session after ownership is restored + action: + click: + role: button + name: Sign out + revealWith: { role: button, name: Open team operations } + expect: + urlIncludes: /auth/sign-in + text: Sign in + - id: enter-primary-owner-approval-email + title: Re-enter the primary owner's credential at the sign-in boundary + action: + fill: + role: textbox + name: Email or username + value: guarantee-{{runId}}-{{deviceId}}@treeseed.local + expect: + text: Sign in + - id: enter-primary-owner-approval-password + title: Enter the primary owner's password for explicit client approval + action: + fill: + css: 'input[name="password"]' + internal: true + value: TreeSeedGuaranteeReset123! + expect: + text: Sign in + - id: approve-primary-owner-session + title: Sign in to Admin as the restored primary owner + action: + click: + role: button + name: Sign in + expect: + urlIncludes: /app + visible: + - scene: app-shell + - id: reopen-members-as-primary-owner + title: Reopen membership administration as the restored primary owner + action: + goto: /app/teams/gt-{{runShort}}-{{deviceId}}/members + expect: + visible: + - css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="project_lead"]' + internal: true + - id: choose-final-reviewer-role + title: Remove the invited user's ownership while preserving another owner + action: + select: + css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"] select[name="roleKey"]' + internal: true + value: reviewer + expect: + text: invite-{{runId}}-{{deviceId}}@treeseed.local + - id: save-final-reviewer-role + title: Persist the final non-owner role through the rendered form + action: + click: + css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"] form[data-ts-method="PATCH"] button[type="submit"]' + internal: true + expect: + text: Member role updated. + visible: + - css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="reviewer"]' + internal: true + - id: reload-team-collection-after-role-change + title: Reload the team collection after ownership and role changes + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: prove-final-role-after-reload + title: Prove the final role remains durable after a fresh page load + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + visible: + - css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="reviewer"]' + internal: true chapters: [] overlays: [] diagrams: [] @@ -127,4 +367,4 @@ runtime: continueOnFailure: false training: {} visualAudit: - enabled: false + enabled: true diff --git a/guarantees/team/membership/scenes/invitation-mismatched-user.scene.yaml b/guarantees/team/membership/scenes/invitation-mismatched-user.scene.yaml new file mode 100644 index 00000000..8dc60329 --- /dev/null +++ b/guarantees/team/membership/scenes/invitation-mismatched-user.scene.yaml @@ -0,0 +1,55 @@ +schemaVersion: treeseed.scene/v1 +id: team.membership.invitation-mismatched-user +title: Mismatched Invitation Account Denial +description: A signed-in user whose email does not match the invitation cannot render or submit acceptance. +audience: [operator, evaluator] +journey: + kind: service + proves: [team.invitation-consent] + minimumSteps: 2 + requiresInteractiveAction: true + consumesState: + - { key: auth.primary-session, kind: browser-storage } + - { key: team.invitation, kind: marker } +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: prove-primary-session + title: Begin from the authenticated primary account + action: { goto: /app/ } + expect: { urlIncludes: /app, visible: [{ scene: app-shell }] } + - id: open-mismatched-invitation + title: Open the exact pending invitation while signed in as a different account + action: + mailpitConfirmLatest: + mailpitUrl: http://127.0.0.1:8025 + email: mismatch-{{runId}}-{{deviceId}}@treeseed.local + subjectIncludes: You're invited to join Verified {{runShort}} {{deviceId}} + expect: + urlIncludes: /team-invites/ + text: Switch to the invited account + notVisible: [{ role: button, name: Accept invitation }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } + capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/membership/scenes/invite-team-members.scene.yaml b/guarantees/team/membership/scenes/invite-team-members.scene.yaml index baa44ab1..745cac73 100644 --- a/guarantees/team/membership/scenes/invite-team-members.scene.yaml +++ b/guarantees/team/membership/scenes/invite-team-members.scene.yaml @@ -8,16 +8,23 @@ audience: journey: kind: service proves: - - Invite Team Members opens the canonical @treeseed/admin record modal form workflow. - - Invite Team Members exercises a service journey instead of only loading /app/teams/visual-audit-team/members. - - Invite Team Members records reviewable evidence for the visible result before activation. - minimumSteps: 2 + - team.member-directory + - team.invitations + minimumSteps: 16 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team + - key: auth.primary-session + kind: browser-storage + - key: team.updated + kind: marker + producesState: + - key: team.invitation + kind: marker + value: + recipient: invite-{{runId}}-{{deviceId}}@treeseed.local + existingRecipient: visual.member@treeseed.io + revokedRecipient: revoke-{{runId}}-{{deviceId}}@treeseed.local + mismatchRecipient: mismatch-{{runId}}-{{deviceId}}@treeseed.local mode: test: true demo: true @@ -82,15 +89,176 @@ workflow: - id: open-entry-route title: Open Invite Team Members action: - goto: /app/teams/visual-audit-team/members + goto: /app/teams expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Invite Team Members service surface + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-members + title: Open membership administration from the run-owned team action: - keyboard: Tab + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true expect: - urlIncludes: /app/teams + urlIncludes: /members + text: Invite a member + - id: enter-invalid-recipient + title: Enter an invalid recipient address + action: + fill: + role: textbox + name: Recipient email + value: not-an-email + expect: + urlIncludes: /members + - id: reject-invalid-recipient + title: Reject the invalid recipient without creating pending state + action: + click: + role: button + name: Send invitation + expect: + urlIncludes: /members + notText: Invitation sent. + - id: fill-recipient + title: Enter a unique invited user + action: + fill: + role: textbox + name: Recipient email + value: invite-{{runId}}-{{deviceId}}@treeseed.local + expect: + text: Invite a member + - id: choose-role + title: Select the initial contributor role + action: + select: + role: combobox + name: Initial role + value: contributor + expect: + text: Invite a member + - id: send-invitation + title: Send the invitation through the member UI + action: + click: + role: button + name: Send invitation + expect: + urlIncludes: /members + text: Invitation sent. + visible: + - css: '[data-ts-toast-id][data-tone="success"]:last-of-type' + internal: true + - id: observe-invitation-email + title: Observe exact invitation delivery in Mailpit + action: + mailpitConfirmLatest: + mailpitUrl: http://127.0.0.1:8025 + email: invite-{{runId}}-{{deviceId}}@treeseed.local + subjectIncludes: You're invited to join Verified {{runShort}} {{deviceId}} + navigate: false + expect: + urlIncludes: /members + text: Pending invitations + - id: fill-existing-recipient + title: Enter the existing verified fixture user + action: + fill: + role: textbox + name: Recipient email + value: visual.member@treeseed.io + expect: + text: Invite a member + - id: send-existing-user-invitation + title: Send an invitation without silently adding the existing user + action: + click: + role: button + name: Send invitation + expect: + visible: + - css: '[data-invite-email="visual.member@treeseed.io"]' + internal: true + notVisible: + - css: '[data-member-email="visual.member@treeseed.io"]' + internal: true + - id: fill-revocable-recipient + title: Enter a second run-scoped recipient for resend and revoke + action: + fill: + role: textbox + name: Recipient email + value: revoke-{{runId}}-{{deviceId}}@treeseed.local + expect: + text: Invite a member + - id: send-revocable-invitation + title: Create the second pending invitation through the UI + action: + click: + role: button + name: Send invitation + expect: + visible: + - css: '[data-invite-email="revoke-{{runId}}-{{deviceId}}@treeseed.local"]' + internal: true + - id: resend-pending-invitation + title: Resend the exact pending invitation + action: + click: + css: '[data-invite-email="revoke-{{runId}}-{{deviceId}}@treeseed.local"] form[action$="/resend"] button' + internal: true + expect: + text: Invitation resent. + visible: + - css: '[data-ts-toast-id][data-tone="success"]:last-of-type' + internal: true + - id: revoke-pending-invitation + title: Revoke the exact pending invitation + action: + click: + css: '[data-invite-email="revoke-{{runId}}-{{deviceId}}@treeseed.local"] form[data-ts-method="DELETE"] button' + internal: true + expect: + text: Invitation revoked. + - id: reload-after-revocation + title: Reload through the durable team collection after revocation + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: reopen-members-after-revocation + title: Reopen pending invitations and prove the revoked record stays absent + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + notVisible: + - css: '[data-invite-email="revoke-{{runId}}-{{deviceId}}@treeseed.local"]' + internal: true + - id: fill-mismatched-recipient + title: Enter a pending recipient used by the mismatched-account denial journey + action: + fill: + role: textbox + name: Recipient email + value: mismatch-{{runId}}-{{deviceId}}@treeseed.local + expect: + text: Invite a member + - id: send-mismatched-invitation + title: Create the exact pending invitation used by the browser denial scene + action: + click: + role: button + name: Send invitation + expect: + visible: + - css: '[data-invite-email="mismatch-{{runId}}-{{deviceId}}@treeseed.local"]' + internal: true chapters: [] overlays: [] diagrams: [] @@ -127,4 +295,4 @@ runtime: continueOnFailure: false training: {} visualAudit: - enabled: false + enabled: true diff --git a/guarantees/team/membership/scenes/remove-team-member.scene.yaml b/guarantees/team/membership/scenes/remove-team-member.scene.yaml index 8097852a..023513ab 100644 --- a/guarantees/team/membership/scenes/remove-team-member.scene.yaml +++ b/guarantees/team/membership/scenes/remove-team-member.scene.yaml @@ -8,16 +8,20 @@ audience: journey: kind: service proves: - - Remove Team Member opens the canonical @treeseed/admin destructive confirmation workflow. - - Remove Team Member exercises a service journey instead of only loading /app/teams/visual-audit-team/members. - - Remove Team Member records reviewable evidence for the visible result before activation. - minimumSteps: 2 + - team.member-removal + - team.member-leave + minimumSteps: 23 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team + - key: auth.primary-session-after-role + kind: browser-storage + - key: team.member-role-changed + kind: marker + producesState: + - key: team.member-removed + kind: marker + - key: auth.primary-session-after-membership + kind: browser-storage mode: test: true demo: true @@ -82,15 +86,245 @@ workflow: - id: open-entry-route title: Open Remove Team Member action: - goto: /app/teams/visual-audit-team/members + goto: /app/teams expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Remove Team Member service surface + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-members + title: Open members for the run-created team + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + text: invite-{{runId}}-{{deviceId}}@treeseed.local + - id: remove-invited-member + title: Remove the invited member + action: + click: + css: '[data-member-email="invite-{{runId}}-{{deviceId}}@treeseed.local"] summary:has-text("Remove")' + internal: true + expect: + urlIncludes: /members + text: Confirm removal + - id: confirm-member-removal + title: Confirm removal through the visible destructive control + action: + click: + role: button + name: Confirm removal + expect: + text: Member removed. + visible: + - css: '[data-ts-toast-id][data-tone="success"]:last-of-type' + internal: true + - id: verify-member-removed + title: Return through the durable team collection + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: sign-out-removing-owner + title: End the owner session before proving the removed user lost access + action: + click: + role: button + name: Sign out + revealWith: { role: button, name: Open team operations } + expect: + urlIncludes: /auth/sign-in + text: Sign in + - id: enter-removed-member-approval-email + title: Re-enter the removed member's credential at the sign-in boundary + action: + fill: + role: textbox + name: Email or username + value: invite-{{runId}}-{{deviceId}}@treeseed.local + expect: + text: Sign in + - id: enter-removed-member-approval-password + title: Enter the removed member's password for explicit Admin approval + action: + fill: + css: 'input[name="password"]' + internal: true + value: TreeSeedInviteGuarantee123! + expect: + text: Sign in + - id: approve-removed-member-session + title: Sign in to Admin for the removed member + action: + click: + role: button + name: Sign in + expect: + urlIncludes: /app + - id: prove-removed-member-lost-access + title: Prove the removed user's team collection no longer exposes the run-created team + action: + goto: /app/teams + expect: + notVisible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: sign-out-removed-member + title: End the removed user's session + action: + click: + role: button + name: Sign out + revealWith: { role: button, name: Open team operations } + expect: + urlIncludes: /auth/sign-in + text: Sign in + - id: enter-existing-member-approval-email + title: Re-enter the existing member's credential at the sign-in boundary + action: + fill: + role: textbox + name: Email or username + value: visual.member@treeseed.io + expect: + text: Sign in + - id: enter-existing-member-approval-password + title: Enter the existing member's password for explicit Admin approval + action: + fill: + css: 'input[name="password"]' + internal: true + value: TreeSeedVisualAudit!2026 + expect: + text: Sign in + - id: approve-existing-member-session + title: Sign in to Admin for the existing member action: - keyboard: Tab + click: + role: button + name: Sign in + expect: + urlIncludes: /app + - id: open-existing-member-team + title: Open the run-created team as the existing member + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-existing-member-overview + title: Enter the team through the contributor-visible overview + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href]:has-text("Overview")' + internal: true + expect: + visible: + - scene: team.navigation + - id: open-existing-member-access + title: Open the existing member's own access controls + action: + click: + role: link + name: Members + expect: + text: Leave team + notVisible: + - role: button + name: Send invitation + - id: leave-as-existing-member + title: Leave the team through the visible self-service control + action: + click: + css: 'form[data-scene="team.member.leave"] button[type="submit"]' + internal: true expect: urlIncludes: /app/teams + text: You left the team. + notVisible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: prove-self-leave-lost-access + title: Prove the former member still cannot recover the team through the collection + action: + goto: /app/teams + expect: + notVisible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: sign-out-former-member + title: End the former member's session + action: + click: + role: button + name: Sign out + revealWith: { role: button, name: Open team operations } + expect: + urlIncludes: /auth/sign-in + text: Sign in + - id: enter-primary-owner-approval-email + title: Re-enter the primary owner's credential at the sign-in boundary + action: + fill: + role: textbox + name: Email or username + value: guarantee-{{runId}}-{{deviceId}}@treeseed.local + expect: + text: Sign in + - id: enter-primary-owner-approval-password + title: Enter the primary owner's password for explicit Admin approval + action: + fill: + css: 'input[name="password"]' + internal: true + value: TreeSeedGuaranteeReset123! + expect: + text: Sign in + - id: approve-primary-owner-session + title: Sign in to Admin for the remaining owner + action: + click: + role: button + name: Sign in + expect: + urlIncludes: /app + - id: open-primary-owner-team-collection + title: Return to the run-created team as its remaining owner + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-last-owner-membership + title: Open the remaining owner's membership controls + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + text: Leave team + visible: + - css: '[data-member-email="guarantee-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="team_owner"]' + internal: true + - id: reject-last-owner-leave + title: Reject self-leave when it would orphan the team + action: + click: + css: 'form[data-scene="team.member.leave"] button[type="submit"]' + internal: true + expect: + urlIncludes: /members + text: A team must keep at least one owner. + clientErrorSourceIncludes: /members + visible: + - css: '[data-ts-toast-id][data-tone="error"]:last-of-type' + internal: true + - css: '[data-member-email="guarantee-{{runId}}-{{deviceId}}@treeseed.local"][data-member-role="team_owner"]' + internal: true chapters: [] overlays: [] diagrams: [] @@ -127,4 +361,4 @@ runtime: continueOnFailure: false training: {} visualAudit: - enabled: false + enabled: true diff --git a/guarantees/team/policy/manage-allocation-sets.guarantee.yaml b/guarantees/team/policy/manage-allocation-sets.guarantee.yaml deleted file mode 100644 index c9c9e344..00000000 --- a/guarantees/team/policy/manage-allocation-sets.guarantee.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.team.policy.manage-allocation-sets.092 -journeyIndex: 92 -type: team -subtype: policy -journey: Manage Allocation Sets -ownerPackage: "@treeseed/admin" -summary: Define team-level capacity budgets limits and eligibility policies; this is distinct from project or agent allocation and belongs outside providers. -status: active -dependencies: - journeys: - - 12 - guarantees: - - guarantee.team.team.create-team.012 -actors: - allowed: - - team_admin - - team_owner - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - - "Journey dependencies must be satisfied: 12" -scene: - required: true - manifest: ./scenes/manage-allocation-sets.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/allocation - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - api.team.permissions.owner -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] -negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - optional: - - mailpit_message -notes: - - Define team-level capacity budgets limits and eligibility policies; this is distinct from project or agent allocation and belongs outside providers. -surface: admin-ui -run: - timeoutSeconds: 300 - requiredForRelease: true diff --git a/guarantees/team/policy/scenes/manage-allocation-sets.scene.yaml b/guarantees/team/policy/scenes/manage-allocation-sets.scene.yaml deleted file mode 100644 index 128e3c51..00000000 --- a/guarantees/team/policy/scenes/manage-allocation-sets.scene.yaml +++ /dev/null @@ -1,130 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team.policy.manage-allocation-sets.092 -title: Manage Allocation Sets -description: Acceptance scene for guarantee.team.policy.manage-allocation-sets.092. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Manage Allocation Sets opens the canonical @treeseed/admin dashboard read model workflow. - - Manage Allocation Sets exercises a service journey instead of only loading /app/capacity/allocation. - - Manage Allocation Sets records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Manage Allocation Sets - action: - goto: /app/capacity/allocation - expect: - urlIncludes: /app/capacity - - id: inspect-service-surface - title: Inspect Manage Allocation Sets service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/team/team/scenes/create-team.scene.yaml b/guarantees/team/scenes/create-team.scene.yaml similarity index 52% rename from guarantees/team/team/scenes/create-team.scene.yaml rename to guarantees/team/scenes/create-team.scene.yaml index 96aad962..e342ae7b 100644 --- a/guarantees/team/team/scenes/create-team.scene.yaml +++ b/guarantees/team/scenes/create-team.scene.yaml @@ -8,17 +8,18 @@ audience: journey: kind: service proves: - - Create Team opens the canonical @treeseed/admin full page form workflow. - - A verified owner can fill and submit the team creation form. - - The created team becomes visible in the authenticated team area for dependent journeys. - minimumSteps: 5 + - team.create + minimumSteps: 8 requiresInteractiveAction: true producesState: - key: team.primary - kind: team + kind: marker + value: + name: gt-{{runShort}}-{{deviceId}} + displayName: Guarantee {{runShort}} {{deviceId}} consumesState: - - key: auth.owner - kind: user + - key: auth.primary-session + kind: browser-storage mode: test: true demo: true @@ -49,6 +50,21 @@ devices: deviceScaleFactor: 1 isMobile: false hasTouch: false + - id: tablet_chromium + title: Tablet Chromium + orientation: portrait + viewport: + width: 820 + height: 1180 + video: + width: 820 + height: 1180 + output: + width: 820 + height: 1180 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true - id: mobile_chromium title: Mobile Chromium orientation: portrait @@ -86,23 +102,41 @@ workflow: goto: /app/teams/new expect: urlIncludes: /app/teams - text: Create team - - id: fill-team-name - title: Fill team name + visible: + - css: '[data-scene="team.create.form"]' + internal: true + - id: enter-invalid-team-name + title: Enter an invalid team name action: fill: - css: '#name' - value: guarantee-team-{{runShort}} + css: '[data-scene="team.create.form"] input[name="name"]' + internal: true + value: Invalid Team Name + expect: + urlIncludes: /app/teams/new + visible: + - css: '[data-scene="team.create.form"]' + internal: true + - id: reject-invalid-team-name + title: Reject invalid input without creating a team + action: + click: + role: button + name: Create team expect: - text: Create team + urlIncludes: /app/teams/new + notText: Team created. - id: fill-team-display-name title: Fill team display name action: fill: css: '#displayName' - value: Guarantee Team {{runShort}} + internal: true + value: Guarantee {{runShort}} {{deviceId}} expect: - text: Create team + visible: + - css: '[data-scene="team.create.form"]' + internal: true - id: fill-team-summary title: Fill team profile summary action: @@ -111,7 +145,20 @@ workflow: name: Profile summary value: Team created by the guarantee service journey for downstream UI verification. expect: - text: Create team + visible: + - css: '[data-scene="team.create.form"]' + internal: true + - id: fill-team-name + title: Fill team name after dependent identity fields + action: + fill: + css: '#name' + internal: true + value: gt-{{runShort}}-{{deviceId}} + expect: + visible: + - css: '[data-scene="team.create.form"]' + internal: true - id: submit-team title: Submit team creation action: @@ -120,12 +167,36 @@ workflow: name: Create team expect: urlIncludes: /app/teams + visible: + - scene: team.overview - id: inspect-service-surface - title: Inspect Create Team service surface + title: Prove the run-created team appears in the collection action: - keyboard: Tab + goto: /app/teams + expect: + urlIncludes: /app/teams + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: await-team-collection-navigation + title: Let the team collection navigation settle before opening members + action: { pause: { mode: timed, durationSeconds: 1 } } expect: urlIncludes: /app/teams + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: inspect-owner-membership + title: Open members and prove owner management controls + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + urlIncludes: /members + text: + - Team members + - Owner chapters: [] overlays: [] diagrams: [] @@ -162,4 +233,4 @@ runtime: continueOnFailure: false training: {} visualAudit: - enabled: false + enabled: true diff --git a/guarantees/team/scenes/delete-team.scene.yaml b/guarantees/team/scenes/delete-team.scene.yaml new file mode 100644 index 00000000..d99e56e0 --- /dev/null +++ b/guarantees/team/scenes/delete-team.scene.yaml @@ -0,0 +1,281 @@ +schemaVersion: treeseed.scene/v1 +id: team.team.delete-team.016 +title: Delete Team +description: Acceptance scene for guarantee.team.team.delete-team.016. +audience: + - operator + - evaluator +journey: + kind: service + proves: + - team.lifecycle + minimumSteps: 14 + requiresInteractiveAction: true + consumesState: + - key: auth.primary-session-after-membership + kind: browser-storage + - key: team.member-removed + kind: marker + producesState: + - key: team.deleted + kind: marker + value: + name: gt-{{runShort}}-{{deviceId}} +mode: + test: true + demo: true + training: true +target: + app: market + environment: local + baseUrl: auto + browser: chromium + viewport: + width: 1600 + height: 900 +devices: + defaultProfile: desktop_chromium + profiles: + - id: desktop_chromium + title: Desktop Chromium + orientation: landscape + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + output: + width: 1920 + height: 1080 + deviceScaleFactor: 1 + isMobile: false + hasTouch: false + - id: mobile_chromium + title: Mobile Chromium + orientation: portrait + viewport: + width: 390 + height: 844 + video: + width: 390 + height: 844 + output: + width: 390 + height: 844 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true +setup: + dev: + required: true + reuseExisting: true + auth: + role: owner + required: true +artifacts: + trace: true + video: true + screenshots: true + console: true + network: true + timeline: true + appLogs: true +workflow: + - id: open-entry-route + title: Open the run-owned team collection + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-members-for-invitation-cleanup + title: Open members to resolve the deliberate mismatch invitation blocker + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/members"]' + internal: true + expect: + visible: + - css: '[data-invite-email="mismatch-{{runId}}-{{deviceId}}@treeseed.local"]' + internal: true + - id: revoke-mismatch-invitation + title: Revoke the remaining mismatched-account invitation before deletion + action: + click: + css: '[data-invite-email="mismatch-{{runId}}-{{deviceId}}@treeseed.local"] form[data-ts-method="DELETE"] button' + internal: true + expect: + text: Invitation revoked. + notVisible: + - css: '[data-invite-email="mismatch-{{runId}}-{{deviceId}}@treeseed.local"]' + internal: true + - id: return-to-lifecycle-entry + title: Return to the team collection after blocker cleanup + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-lifecycle + title: Open owner-only lifecycle controls + action: + clickVisibleSequence: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href]:has-text("Overview")' + internal: true + - role: link + name: Lifecycle + expect: + text: No active archive blockers were found. + - id: archive-team + title: Archive the team through the visible lifecycle control + action: + click: + css: 'form[data-scene="team.archive"] button[type="submit"]' + internal: true + expect: + urlIncludes: /app/teams + text: Team archived. + - id: reopen-archived-lifecycle + title: Reopen the archived team and its recovery window + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/delete"]' + internal: true + expect: + visible: + - css: '[data-ts-countdown]' + internal: true + - id: prove-archived-deletion-available + title: Prove deletion remains a distinct immediate operation while archived + action: + keyboard: Tab + expect: + text: Delete team permanently + - id: restore-team + title: Restore the archived team during its recovery window + action: + click: + css: 'form[data-scene="team.restore"] button[type="submit"]' + internal: true + expect: + urlIncludes: /app/teams/ + text: Operational overview + - id: return-to-collection + title: Return to the team collection + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: reopen-active-lifecycle + title: Reopen lifecycle after restoration and delete without another archive + action: + clickVisibleSequence: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href]:has-text("Overview")' + internal: true + - role: link + name: Lifecycle + expect: + text: Deletion is immediate + - id: enter-incorrect-confirmation + title: Enter an incorrect deletion confirmation + action: + fill: + role: textbox + name: Type "DELETE gt-{{runShort}}-{{deviceId}}" exactly + value: wrong-team + expect: + text: Delete team permanently + - id: enter-reauthentication + title: Reauthenticate for the destructive operation + action: + fill: + role: textbox + name: Current password + value: TreeSeedGuaranteeReset123! + expect: + text: Delete team permanently + - id: reject-incorrect-confirmation + title: Reject an incorrect exact-name confirmation + action: + click: + css: 'form[data-scene="team.delete"] button[type="submit"]' + internal: true + expect: + urlIncludes: /delete + text: Type + clientErrorSourceIncludes: /delete + - id: enter-exact-confirmation + title: Enter the exact deletion confirmation + action: + fill: + role: textbox + name: Type "DELETE gt-{{runShort}}-{{deviceId}}" exactly + value: DELETE gt-{{runShort}}-{{deviceId}} + expect: + text: Delete team permanently + - id: delete-team + title: Permanently delete the run-owned team + action: + click: + css: 'form[data-scene="team.delete"] button[type="submit"]' + internal: true + expect: + urlIncludes: /app/teams + notVisible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: verify-team-lookup-cleared + title: Verify the deleted team no longer resolves + action: + apiRequest: + base: web + method: GET + path: /t/gt-{{runShort}}-{{deviceId}} + expectedStatus: 404 + expect: + urlIncludes: /app/teams + notVisible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: + format: mp4 + fps: 30 + resolution: + width: 1920 + height: 1080 + capture: + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + evidenceFit: fixed-browser +runtime: + mode: training + timeouts: + sceneSeconds: 300 + chapterSeconds: 120 + stepSeconds: 60 + checkpoints: + enabled: true + defaultResumable: true + everyStep: true + progress: + heartbeatSeconds: 15 + failure: + continueOnFailure: false +training: {} +visualAudit: + enabled: true diff --git a/guarantees/team/scenes/edit-team-settings.scene.yaml b/guarantees/team/scenes/edit-team-settings.scene.yaml new file mode 100644 index 00000000..53f4e9b0 --- /dev/null +++ b/guarantees/team/scenes/edit-team-settings.scene.yaml @@ -0,0 +1,234 @@ +schemaVersion: treeseed.scene/v1 +id: team.team.edit-team-settings.014 +title: Edit Team Settings +description: Acceptance scene for guarantee.team.team.edit-team-settings.014. +audience: + - operator + - evaluator +journey: + kind: service + proves: + - team.identity-settings + minimumSteps: 9 + requiresInteractiveAction: true + consumesState: + - key: auth.primary-session + kind: browser-storage + - key: team.active + kind: marker + producesState: + - key: team.updated + kind: marker +mode: + test: true + demo: true + training: true +target: + app: market + environment: local + baseUrl: auto + browser: chromium + viewport: + width: 1600 + height: 900 +devices: + defaultProfile: desktop_chromium + profiles: + - id: desktop_chromium + title: Desktop Chromium + orientation: landscape + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + output: + width: 1920 + height: 1080 + deviceScaleFactor: 1 + isMobile: false + hasTouch: false + - id: tablet_chromium + title: Tablet Chromium + orientation: portrait + viewport: + width: 820 + height: 1180 + video: + width: 820 + height: 1180 + output: + width: 820 + height: 1180 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true + - id: mobile_chromium + title: Mobile Chromium + orientation: portrait + viewport: + width: 390 + height: 844 + video: + width: 390 + height: 844 + output: + width: 390 + height: 844 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true +setup: + dev: + required: true + reuseExisting: true + auth: + role: owner + required: true +artifacts: + trace: true + video: true + screenshots: true + console: true + network: true + timeline: true + appLogs: true +workflow: + - id: open-entry-route + title: Open Edit Team Settings + action: + goto: /app/teams + expect: + urlIncludes: /app/teams + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-settings-control + title: Open settings from the exact run-owned team card + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/edit"]' + internal: true + expect: + urlIncludes: /edit + text: Settings + - id: force-stale-version + title: Prepare a stale optimistic version without mutating the team + action: + fill: + css: 'input[name="expectedUpdatedAt"]' + internal: true + value: 2000-01-01T00:00:00.000Z + expect: + text: Settings + - id: reject-stale-update + title: Reject the stale update and preserve the persisted identity + action: + click: + role: button + name: Save team + expect: + urlIncludes: /edit + text: changed + clientErrorSourceIncludes: /edit + - id: return-to-current-settings + title: Reload the current version through the collection + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: reopen-current-settings + title: Reopen settings with the current optimistic version + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href$="/edit"]' + internal: true + expect: + text: Settings + - id: update-display-name + title: Update the public team display name + action: + fill: + css: '#displayName' + internal: true + value: Verified {{runShort}} {{deviceId}} + expect: + text: Save team + - id: update-summary + title: Update the identity-only public summary + action: + fill: + role: textbox + name: Profile summary + value: Public identity verified by a complete team settings service journey. + expect: + text: Save team + - id: publish-team-identity + title: Make the team identity publicly discoverable + action: + select: + role: combobox + name: Profile visibility + value: public + expect: + text: Save team + - id: save-team + title: Persist the team settings + action: + click: + role: button + name: Save team + expect: + urlIncludes: /edit + text: Team saved. + visible: + - css: '[data-ts-toast-id][data-tone="success"]:last-of-type' + internal: true + - id: reload-team + title: Reload persisted settings + action: + goto: /app/teams + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: + format: mp4 + fps: 30 + resolution: + width: 1920 + height: 1080 + capture: + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + evidenceFit: fixed-browser +runtime: + mode: training + timeouts: + sceneSeconds: 300 + chapterSeconds: 120 + stepSeconds: 60 + checkpoints: + enabled: true + defaultResumable: true + everyStep: true + progress: + heartbeatSeconds: 15 + failure: + continueOnFailure: false +training: {} +visualAudit: + enabled: true diff --git a/guarantees/team/scenes/negative/anonymous-team-access.scene.yaml b/guarantees/team/scenes/negative/anonymous-team-access.scene.yaml new file mode 100644 index 00000000..ad7e3eb3 --- /dev/null +++ b/guarantees/team/scenes/negative/anonymous-team-access.scene.yaml @@ -0,0 +1,55 @@ +schemaVersion: treeseed.scene/v1 +id: team.negative.anonymous-access +title: Anonymous Team Administration Denial +description: Anonymous visitors cannot reach team collection, creation, or operational overview controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [team.create, team.active-selection, team.operational-overview] + minimumSteps: 3 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, orientation: portrait, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: anonymous, required: false } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: deny-team-collection + title: Redirect anonymous collection access + action: { goto: /app/teams } + expect: { urlIncludes: "/auth/sign-in?returnTo=", text: Sign in } + - id: exercise-sign-in-boundary + title: Render the credential form without a consent interstitial + action: { goto: /auth/sign-in } + expect: + urlIncludes: "/auth/sign-in" + visible: [{ role: textbox, name: Email or username }, { role: button, name: Sign in }] + - id: deny-team-creation + title: Redirect anonymous create access without rendering mutation controls + action: { goto: /app/teams/new } + expect: + urlIncludes: "/auth/sign-in?returnTo=" + notVisible: [{ role: button, name: Create team }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } + capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/scenes/negative/edit-contributor.scene.yaml b/guarantees/team/scenes/negative/edit-contributor.scene.yaml new file mode 100644 index 00000000..ded9c988 --- /dev/null +++ b/guarantees/team/scenes/negative/edit-contributor.scene.yaml @@ -0,0 +1,55 @@ +schemaVersion: treeseed.scene/v1 +id: team.negative.edit-contributor +title: Contributor Team Settings Denial +description: A contributor can view team context but cannot render or submit identity controls. +audience: [operator, evaluator] +journey: + kind: service + proves: [team.identity-settings] + minimumSteps: 2 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, orientation: portrait, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: member, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: deny-settings-form + title: Omit identity mutation controls for contributors + action: + goto: + path: /app/teams/visual-audit-team/edit + expectedStatus: 403 + expect: + text: Team controls unavailable + notVisible: [{ role: button, name: Save team }] + - id: return-to-overview + title: Return to the safe team collection + action: + click: { role: link, name: Back to teams } + expect: + urlIncludes: /app/teams + visible: [{ scene: team.collection }] +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } + capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/scenes/negative/lifecycle-project-lead.scene.yaml b/guarantees/team/scenes/negative/lifecycle-project-lead.scene.yaml new file mode 100644 index 00000000..2658cf7d --- /dev/null +++ b/guarantees/team/scenes/negative/lifecycle-project-lead.scene.yaml @@ -0,0 +1,51 @@ +schemaVersion: treeseed.scene/v1 +id: team.negative.lifecycle-project-lead +title: Project Lead Lifecycle Denial +description: Project leads cannot archive, restore, or permanently delete a team. +audience: [operator, evaluator] +journey: + kind: service + proves: [team.lifecycle] + minimumSteps: 2 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: admin, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: deny-lifecycle-controls + title: Omit owner-only lifecycle controls + action: { goto: /app/teams/visual-audit-team/delete } + expect: + text: Owner access required + notVisible: + - { role: button, name: Archive team } + - { role: button, name: Delete team permanently } + - id: return-to-overview + title: Preserve project lead operational access + action: + click: { role: link, name: Team overview } + expect: { urlIncludes: /app/teams/visual-audit-team, text: Operational overview } +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } + capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/scenes/negative/members-contributor.scene.yaml b/guarantees/team/scenes/negative/members-contributor.scene.yaml new file mode 100644 index 00000000..b7c264f5 --- /dev/null +++ b/guarantees/team/scenes/negative/members-contributor.scene.yaml @@ -0,0 +1,73 @@ +schemaVersion: treeseed.scene/v1 +id: team.negative.members-contributor +title: Contributor Member Directory and Administration Denial +description: Contributors can list and search teammates while invitation, role, ownership, and removal controls stay absent. +audience: [operator, evaluator] +journey: + kind: service + proves: [team.member-directory, team.invitations, team.member-roles, team.member-removal] + minimumSteps: 3 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: member, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-member-directory + title: Show the member directory without administration controls + action: { goto: /app/teams/visual-audit-team/members } + expect: + text: Team members + visible: + - { css: "#team-member-search", internal: true } + - { css: '[data-member-email="visual.member@treeseed.io"]', internal: true } + notVisible: + - { role: button, name: Send invitation } + - { role: button, name: Save } + - { role: button, name: Transfer ownership } + - { role: button, name: Confirm removal } + - id: search-member-directory + title: Search members through the visible directory + action: + fill: + role: searchbox + name: Search members + value: contributor + expect: + visible: + - { css: "#team-member-search", internal: true } + - id: submit-member-search + title: Return matching members without exposing mutation controls + action: + click: { role: button, name: Search } + expect: + urlIncludes: q=contributor + text: Contributor + notVisible: + - { role: button, name: Send invitation } + - { role: button, name: Save } + - { role: button, name: Transfer ownership } + - { role: button, name: Confirm removal } +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } + capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/scenes/negative/overview-nonmember.scene.yaml b/guarantees/team/scenes/negative/overview-nonmember.scene.yaml new file mode 100644 index 00000000..bcfc9882 --- /dev/null +++ b/guarantees/team/scenes/negative/overview-nonmember.scene.yaml @@ -0,0 +1,52 @@ +schemaVersion: treeseed.scene/v1 +id: team.negative.overview-nonmember +title: Non-member Team Overview Denial +description: An authenticated comparison user cannot discover or open the run-owned team. +audience: [operator, evaluator] +journey: + kind: service + proves: [team.collection, team.operational-overview] + minimumSteps: 2 + requiresInteractiveAction: true +mode: { test: true, demo: true, training: true } +target: { app: market, environment: local, baseUrl: auto, browser: chromium, viewport: { width: 1600, height: 900 } } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, orientation: portrait, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: member, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: hide-run-team + title: Hide the run-owned team from the comparison principal + action: { goto: /app/teams } + expect: + urlIncludes: /app/teams + notText: Verified {{runShort}} {{deviceId}} + - id: exercise-available-overview + title: Preserve access to the comparison user's own overview + action: + click: { role: link, name: Overview } + expect: + urlIncludes: /app/teams/ + text: Operational overview +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } + capture: { viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, evidenceFit: fixed-browser } +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/scenes/switch-active-team.scene.yaml b/guarantees/team/scenes/switch-active-team.scene.yaml new file mode 100644 index 00000000..f1c2a931 --- /dev/null +++ b/guarantees/team/scenes/switch-active-team.scene.yaml @@ -0,0 +1,187 @@ +schemaVersion: treeseed.scene/v1 +id: team.team.switch-active-team.013 +title: Switch Active Team +description: Acceptance scene for guarantee.team.team.switch-active-team.013. +audience: + - operator + - evaluator +journey: + kind: service + proves: + - team.active-selection + minimumSteps: 4 + requiresInteractiveAction: true + consumesState: + - key: auth.primary-session + kind: browser-storage + - key: team.primary + kind: marker + producesState: + - key: team.active-session + kind: browser-storage + - key: team.active + kind: marker +mode: + test: true + demo: true + training: true +target: + app: market + environment: local + baseUrl: auto + browser: chromium + viewport: + width: 1600 + height: 900 +devices: + defaultProfile: desktop_chromium + profiles: + - id: desktop_chromium + title: Desktop Chromium + orientation: landscape + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + output: + width: 1920 + height: 1080 + deviceScaleFactor: 1 + isMobile: false + hasTouch: false + - id: tablet_chromium + title: Tablet Chromium + orientation: portrait + viewport: + width: 820 + height: 1180 + video: + width: 820 + height: 1180 + output: + width: 820 + height: 1180 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true + - id: mobile_chromium + title: Mobile Chromium + orientation: portrait + viewport: + width: 390 + height: 844 + video: + width: 390 + height: 844 + output: + width: 390 + height: 844 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true +setup: + dev: + required: true + reuseExisting: true + auth: + role: owner + required: true +artifacts: + trace: true + video: true + screenshots: true + console: true + network: true + timeline: true + appLogs: true +workflow: + - id: open-entry-route + title: Open Switch Active Team + action: + goto: /app/teams + expect: + urlIncludes: /app/teams + visible: + - css: '[data-scene="team.collection"]' + internal: true + - css: '[data-team-display-name="Tree Seed"]' + internal: true + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - css: '[data-scene="team.collection"] > .ts-page-header' + internal: true + notVisible: + - css: '[data-scene="team.collection"] [data-active="true"]' + internal: true + - id: switch-to-personal-team + title: Select the personal team through its explicit collection control + action: + click: + css: '[data-team-display-name="Tree Seed"] [data-scene="team.active.set"] button' + internal: true + expect: + visible: + - css: '[data-team-display-name="Tree Seed"][data-active="true"]' + internal: true + - id: switch-to-created-team + title: Select the created team through its explicit collection control + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] [data-scene="team.active.set"] button' + internal: true + expect: + visible: + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"][data-active="true"]' + internal: true + - id: reload-active-team + title: Prove active-team cookie persistence after reload + action: + goto: /app + expect: + urlIncludes: /app + visible: + - css: '[data-scene="start.orientation"] .ts-page-header' + internal: true + - css: '[data-scene="start.orientation"] .ts-page-header:has-text("Choose how to engage with Guarantee {{runShort}} {{deviceId}}")' + internal: true + - css: '[data-scene="start.orientation"] a:has-text("Enter Agent Lab")' + internal: true +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: + format: mp4 + fps: 30 + resolution: + width: 1920 + height: 1080 + capture: + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + evidenceFit: fixed-browser +runtime: + mode: training + timeouts: + sceneSeconds: 300 + chapterSeconds: 120 + stepSeconds: 60 + checkpoints: + enabled: true + defaultResumable: true + everyStep: true + progress: + heartbeatSeconds: 15 + failure: + continueOnFailure: false +training: {} +visualAudit: + enabled: true diff --git a/guarantees/team/scenes/view-public-team-profile.scene.yaml b/guarantees/team/scenes/view-public-team-profile.scene.yaml new file mode 100644 index 00000000..1119dd6e --- /dev/null +++ b/guarantees/team/scenes/view-public-team-profile.scene.yaml @@ -0,0 +1,102 @@ +schemaVersion: treeseed.scene/v1 +id: team.team.view-public-team-profile.021 +title: View Public Team Profile +description: Anonymous public-knowledge and redaction journey for the active run-owned team. +audience: [operator, evaluator] +journey: + kind: service + proves: [team.public-profile] + minimumSteps: 3 + requiresInteractiveAction: true + consumesState: + - key: team.updated + kind: marker +mode: { test: true, demo: true, training: true } +target: + app: market + environment: local + baseUrl: auto + browser: chromium + viewport: { width: 1600, height: 900 } +devices: + defaultProfile: desktop_chromium + profiles: + - id: desktop_chromium + title: Desktop Chromium + orientation: landscape + viewport: { width: 1600, height: 900 } + video: { width: 1600, height: 900 } + output: { width: 1920, height: 1080 } + deviceScaleFactor: 1 + isMobile: false + hasTouch: false + - id: tablet_chromium + title: Tablet Chromium + orientation: portrait + viewport: { width: 820, height: 1180 } + video: { width: 820, height: 1180 } + output: { width: 820, height: 1180 } + deviceScaleFactor: 2 + isMobile: true + hasTouch: true + - id: mobile_chromium + title: Mobile Chromium + orientation: portrait + viewport: { width: 390, height: 844 } + video: { width: 390, height: 844 } + output: { width: 390, height: 844 } + deviceScaleFactor: 2 + isMobile: true + hasTouch: true +setup: + dev: { required: true, reuseExisting: true } + auth: { role: anonymous, required: false } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +workflow: + - id: open-public-profile + title: Open the anonymous team knowledge profile + action: { goto: "/t/gt-{{runShort}}-{{deviceId}}" } + expect: + urlIncludes: /t/gt- + text: Verified {{runShort}} {{deviceId}} + visible: + - { scene: knowledge.profile } + - { scene: knowledge.identity } + - { scene: knowledge.activity } + - id: inspect-public-appearance-control + title: Exercise the public appearance control + action: + click: { css: '[data-testid="appearance-menu-trigger"]', internal: true } + expect: + urlIncludes: /t/gt- + visible: + - { css: '[data-ts-theme-scheme-select]', internal: true } + - id: prove-redaction + title: Prove private operations remain absent while public knowledge sections render + action: { goto: "/t/gt-{{runShort}}-{{deviceId}}" } + expect: + text: Published knowledge + notText: "@treeseed.local" + notVisible: + - { scene: team.navigation } + - { role: link, name: Manage members } + - { role: link, name: View projects } +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } + capture: + viewport: { width: 1600, height: 900 } + video: { width: 1600, height: 900 } + evidenceFit: fixed-browser +runtime: + mode: training + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } +training: {} +visualAudit: { enabled: true } diff --git a/guarantees/team/scenes/view-team-overview.scene.yaml b/guarantees/team/scenes/view-team-overview.scene.yaml new file mode 100644 index 00000000..e07134b7 --- /dev/null +++ b/guarantees/team/scenes/view-team-overview.scene.yaml @@ -0,0 +1,215 @@ +schemaVersion: treeseed.scene/v1 +id: team.team.view-team-overview.015 +title: View Team Overview +description: Acceptance scene for guarantee.team.team.view-team-overview.015. +audience: + - operator + - evaluator +journey: + kind: service + proves: + - team.collection + - team.operational-overview + - team.public-profile + minimumSteps: 6 + requiresInteractiveAction: true + consumesState: + - key: auth.primary-session + kind: browser-storage + - key: team.updated + kind: marker +mode: + test: true + demo: true + training: true +target: + app: market + environment: local + baseUrl: auto + browser: chromium + viewport: + width: 1600 + height: 900 +devices: + defaultProfile: desktop_chromium + profiles: + - id: desktop_chromium + title: Desktop Chromium + orientation: landscape + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + output: + width: 1920 + height: 1080 + deviceScaleFactor: 1 + isMobile: false + hasTouch: false + - id: tablet_chromium + title: Tablet Chromium + orientation: portrait + viewport: + width: 820 + height: 1180 + video: + width: 820 + height: 1180 + output: + width: 820 + height: 1180 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true + - id: mobile_chromium + title: Mobile Chromium + orientation: portrait + viewport: + width: 390 + height: 844 + video: + width: 390 + height: 844 + output: + width: 390 + height: 844 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true +setup: + dev: + required: true + reuseExisting: true + auth: + role: owner + required: true +artifacts: + trace: true + video: true + screenshots: true + console: true + network: true + timeline: true + appLogs: true +workflow: + - id: open-team-collection + title: Open the team collection without changing active context + action: + goto: /app/teams + expect: + urlIncludes: /app/teams + visible: + - scene: team.collection + - css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"]' + internal: true + - id: open-operational-overview + title: Open the authenticated operational overview + action: + click: + css: '[data-team-name="gt-{{runShort}}-{{deviceId}}"] a[href]:has-text("Overview")' + internal: true + expect: + urlIncludes: /app/teams/ + text: Content activity unavailable + visible: + - scene: team.overview + - scene: team.navigation + - css: '[data-scene="team.navigation"] a[aria-current="page"]' + internal: true + - css: '.ts-disclosure-list' + internal: true + - scene: team.overview.content-activity + - id: open-team-activity-help + title: Open team activity guidance from the audit panel + action: + click: { css: 'button[data-ts-help-knowledge-page-id="team.activity"]', internal: true } + expect: + visible: + - { css: '[data-ts-help-dialog][open]', internal: true } + text: Help is unavailable + - id: close-team-activity-help + title: Close team activity guidance and restore focus + action: + click: { role: button, name: Close help } + expect: + notVisible: + - { css: '[data-ts-help-dialog][open]', internal: true } + focused: { css: 'button[data-ts-help-knowledge-page-id="team.activity"]', internal: true } + - id: inspect-domain-summaries + title: Continue to the canonical projects collection when summaries are unavailable + action: + goto: /app/projects + expect: + urlIncludes: /app/projects + - id: return-and-inspect-navigation + title: Return through the shared team navigation + action: + goto: /app/teams/gt-{{runShort}}-{{deviceId}} + expect: + visible: + - scene: team.navigation + - scene: team.overview.audit + text: Audit projection unavailable + - id: open-public-profile-with-team-context + title: Open the public profile through access-checked team navigation + action: + click: + role: link + name: Public profile + expect: + urlIncludes: /t/gt- + visible: + - scene: knowledge.profile + - scene: team.navigation + - css: '[data-scene="team.navigation"] a[aria-current="page"]' + internal: true + text: Public knowledge + - id: return-to-members + title: Use the authorized member-management tab + action: + click: + role: link + name: Members + expect: + urlIncludes: /members + visible: + - scene: team.navigation +chapters: [] +overlays: [] +diagrams: [] +render: + remotion: + composition: treeseed-training-default + output: + format: mp4 + fps: 30 + resolution: + width: 1920 + height: 1080 + capture: + viewport: + width: 1600 + height: 900 + video: + width: 1600 + height: 900 + evidenceFit: fixed-browser +runtime: + mode: training + timeouts: + sceneSeconds: 300 + chapterSeconds: 120 + stepSeconds: 60 + checkpoints: + enabled: true + defaultResumable: true + everyStep: true + progress: + heartbeatSeconds: 15 + failure: + continueOnFailure: false +training: {} +visualAudit: + enabled: true diff --git a/guarantees/team/team-management.ui-feature.yaml b/guarantees/team/team-management.ui-feature.yaml new file mode 100644 index 00000000..96a70cf5 --- /dev/null +++ b/guarantees/team/team-management.ui-feature.yaml @@ -0,0 +1,158 @@ +schemaVersion: treeseed.ui-feature/v1 +id: admin.team-management +ownerPackage: "@treeseed/admin" +routes: + - /app/teams + - /app/teams/active + - /app/teams/new + - /app/teams/[teamId] + - /app/teams/[teamId]/edit + - /app/teams/[teamId]/members + - /app/teams/[teamId]/delete + - /team-invites/[token]/accept + - /t/[name] +devices: + - desktop_chromium + - tablet_chromium + - mobile_chromium +states: + - loading + - empty + - unavailable + - forbidden + - validation + - conflict + - success + - archived + - destructive +capabilities: + - id: team.collection + routes: [/app/teams] + actions: [open-overview, open-settings, open-members, open-lifecycle] + states: [loading, empty, unavailable, active, archived, forbidden] + actors: + allowed: [team_owner, project_lead, contributor, reviewer, viewer] + forbidden: [anonymous_user, non_member] + guaranteeIds: [guarantee.team.team.view-team-overview.015] + - id: team.create + routes: [/app/teams/new] + actions: [validate, create] + states: [validation, conflict, success, unavailable] + actors: + allowed: [verified_user] + forbidden: [anonymous_user, unverified_user, service_principal] + guaranteeIds: [guarantee.team.team.create-team.012] + - id: team.active-selection + routes: [/app/teams, /app/teams/active, /app] + actions: [set-active, clear-invalid-preference] + states: [success, forbidden, unavailable] + actors: + allowed: [team_member] + forbidden: [anonymous_user, non_member] + guaranteeIds: [guarantee.team.team.switch-active-team.013] + - id: team.identity-settings + routes: ["/app/teams/[teamId]/edit"] + actions: [preview, validate, update] + states: [validation, conflict, success, archived, forbidden, unavailable] + actors: + allowed: [team_owner, project_lead] + forbidden: [contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.team.team.edit-team-settings.014] + - id: team.operational-overview + routes: ["/app/teams/[teamId]"] + actions: [inspect-summary, inspect-content-activity, follow-domain-link, inspect-audit] + states: [active, archived, forbidden, unavailable, not-found] + actors: + allowed: [team_member] + forbidden: [anonymous_user, non_member] + guaranteeIds: [guarantee.team.team.view-team-overview.015] + - id: team.public-profile + routes: ["/t/[name]"] + actions: [view-public-identity, browse-public-knowledge, inspect-public-activity, use-authorized-team-navigation] + states: [active, authenticated-member, empty, not-found] + actors: + allowed: [anonymous_user, team_member] + forbidden: [none] + guaranteeIds: [guarantee.team.team.view-team-overview.015, guarantee.team.team.view-public-team-profile.021] + - id: team.member-directory + routes: ["/app/teams/[teamId]/members"] + actions: [list-members, search-members, inspect-role] + states: [empty, success, archived, forbidden, unavailable] + actors: + allowed: [team_member] + forbidden: [non_member, anonymous_user] + guaranteeIds: [guarantee.team.membership.invite-team-members.017] + - id: team.invitations + routes: ["/app/teams/[teamId]/members"] + actions: [validate, create, list, resend, revoke] + states: [empty, validation, conflict, success, archived, forbidden, unavailable] + actors: + allowed: [team_owner, project_lead] + forbidden: [contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.team.membership.invite-team-members.017] + - id: team.invitation-consent + routes: ["/team-invites/[token]/accept"] + actions: [preview, sign-in, register, switch-account, accept, select-active] + states: [valid, expired, revoked, accepted, invalid, email-mismatch, success] + actors: + allowed: [invited_user] + forbidden: [mismatched_user] + guaranteeIds: [guarantee.team.membership.accept-team-invitation.018] + - id: team.member-roles + routes: ["/app/teams/[teamId]/members"] + actions: [change-non-owner-role] + states: [validation, conflict, success, last-owner, forbidden] + actors: + allowed: [team_owner, project_lead] + forbidden: [contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.team.membership.change-member-role.019] + - id: team.ownership + routes: ["/app/teams/[teamId]/members"] + actions: [grant-owner, remove-owner, transfer-owner] + states: [validation, conflict, success, last-owner, forbidden] + actors: + allowed: [team_owner] + forbidden: [project_lead, contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.team.membership.change-member-role.019] + - id: team.member-removal + routes: ["/app/teams/[teamId]/members"] + actions: [inspect-blockers, confirm-remove] + states: [blocked, confirmation, success, lost-access, forbidden] + actors: + allowed: [team_owner, project_lead] + forbidden: [contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.team.membership.remove-team-member.020] + - id: team.member-leave + routes: ["/app/teams/[teamId]/members"] + actions: [self-leave] + states: [confirmation, success, lost-access, last-owner, forbidden] + actors: + allowed: [current_member] + forbidden: [last_owner, non_member, anonymous_user] + guaranteeIds: [guarantee.team.membership.remove-team-member.020] + - id: team.lifecycle + routes: ["/app/teams/[teamId]/delete"] + actions: [inspect-blockers, archive, inspect-restore-countdown, restore, reauthenticate, delete-permanently] + states: [blocked, active, archived, restore-window, validation, success, forbidden, unavailable] + actors: + allowed: [team_owner] + forbidden: [project_lead, contributor, viewer, non_member, anonymous_user] + guaranteeIds: [guarantee.team.team.delete-team.016] +requiredGuarantees: + - guarantee.team.team.create-team.012 + - guarantee.team.team.switch-active-team.013 + - guarantee.team.team.edit-team-settings.014 + - guarantee.team.team.view-team-overview.015 + - guarantee.team.team.delete-team.016 + - guarantee.team.membership.invite-team-members.017 + - guarantee.team.membership.accept-team-invitation.018 + - guarantee.team.membership.change-member-role.019 + - guarantee.team.membership.remove-team-member.020 + - guarantee.team.team.view-public-team-profile.021 +requirements: + accessibility: true + console: true + network: true + visual: true + durableState: true + cleanup: true diff --git a/guarantees/team/team/create-team.guarantee.yaml b/guarantees/team/team/create-team.guarantee.yaml index 273613c1..07258c4b 100644 --- a/guarantees/team/team/create-team.guarantee.yaml +++ b/guarantees/team/team/create-team.guarantee.yaml @@ -5,7 +5,7 @@ type: team subtype: team journey: Create Team ownerPackage: "@treeseed/admin" -summary: Create the team boundary that owns projects capacity policy members and billing-like settings; this should be API-backed durable state. +summary: Create the durable team identity and membership boundary used by active-team selection and team management. status: active dependencies: journeys: @@ -17,10 +17,10 @@ actors: - verified_user forbidden: - anonymous_user - - unauthorized_user devices: required: - desktop_chromium + - tablet_chromium - mobile_chromium gates: - core @@ -29,11 +29,14 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - "Journey dependencies must be satisfied: 4" +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.create] scene: required: true - manifest: ./scenes/create-team.scene.yaml + manifest: ../scenes/create-team.scene.yaml + executionKey: admin.team.create mode: acceptance: true demo: true @@ -49,18 +52,19 @@ scene: api: required: true verifierRefs: - - api.team.create + - api.team.create.correlated content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.team.create.correlated] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: anonymous-denied + actor: anonymous_user + sceneManifest: ../scenes/negative/anonymous-team-access.scene.yaml + executionKey: admin.team.negative.anonymous-access + verifierRefs: [api.team.create.anonymous-denied] evidence: required: - playwright_trace @@ -69,7 +73,7 @@ evidence: optional: - mailpit_message notes: - - Create the team boundary that owns projects capacity policy members and billing-like settings; this should be API-backed durable state. + - Create the durable team identity and membership boundary used by active-team selection and team management. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/team/team/delete-team.guarantee.yaml b/guarantees/team/team/delete-team.guarantee.yaml index ed6c01dd..9f57efbc 100644 --- a/guarantees/team/team/delete-team.guarantee.yaml +++ b/guarantees/team/team/delete-team.guarantee.yaml @@ -5,20 +5,20 @@ type: team subtype: team journey: Delete Team ownerPackage: "@treeseed/admin" -summary: Delete or archive a team only after checking projects hosts capacity and content ownership; likely requires explicit retention and transfer rules. +summary: Archive and restore a team within its recovery window, or immediately delete it after blocker checks and explicit reauthentication. status: active dependencies: - journeys: - - 12 + journeys: [] guarantees: - - guarantee.team.team.create-team.012 + - guarantee.team.membership.remove-team-member.020 + - guarantee.team.team.view-team-overview.015 + - guarantee.team.team.view-public-team-profile.021 actors: allowed: - team_admin - team_owner forbidden: - - anonymous_user - - unauthorized_user + - project_lead devices: required: - desktop_chromium @@ -30,16 +30,19 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - - "Journey dependencies must be satisfied: 12" + - Membership lifecycle and public profile verification must finish before deletion. +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.lifecycle] scene: required: true - manifest: ./scenes/delete-team.scene.yaml + manifest: ../scenes/delete-team.scene.yaml + executionKey: admin.team.delete mode: acceptance: true demo: true training: true - entryRoute: /app/teams/visual-audit-team/delete + entryRoute: /app/teams/[teamId]/delete componentContract: destructive-confirmation service journey expectedEvidence: - playwright_trace @@ -50,18 +53,18 @@ scene: api: required: true verifierRefs: - - api.team.deletion-blockers + - api.team.delete.correlated content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.team.delete.correlated] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: project-lead-denied + actor: project_lead + sceneManifest: ../scenes/negative/lifecycle-project-lead.scene.yaml + verifierRefs: [api.team.lifecycle.project-lead-denied] evidence: required: - playwright_trace @@ -70,7 +73,7 @@ evidence: optional: - mailpit_message notes: - - Delete or archive a team only after checking projects hosts capacity and content ownership; likely requires explicit retention and transfer rules. + - Archiving is reversible during the displayed recovery window; permanent deletion is separately available without an archive delay and requires blocker checks, the exact team name, and the current password. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/team/team/edit-team-settings.guarantee.yaml b/guarantees/team/team/edit-team-settings.guarantee.yaml index 7bf0883e..ef8968b5 100644 --- a/guarantees/team/team/edit-team-settings.guarantee.yaml +++ b/guarantees/team/team/edit-team-settings.guarantee.yaml @@ -9,19 +9,19 @@ summary: Update team metadata and policy knobs; should not mutate package or pro status: active dependencies: journeys: - - 12 + - 13 guarantees: - - guarantee.team.team.create-team.012 + - guarantee.team.team.switch-active-team.013 actors: allowed: - team_admin - team_owner forbidden: - - anonymous_user - - unauthorized_user + - contributor devices: required: - desktop_chromium + - tablet_chromium - mobile_chromium gates: - core @@ -30,16 +30,19 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - "Journey dependencies must be satisfied: 12" +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.identity-settings] scene: required: true - manifest: ./scenes/edit-team-settings.scene.yaml + manifest: ../scenes/edit-team-settings.scene.yaml + executionKey: admin.team.edit mode: acceptance: true demo: true training: true - entryRoute: /app/teams/visual-audit-team/edit + entryRoute: /app/teams/[teamId]/edit componentContract: full-page-form service journey expectedEvidence: - playwright_trace @@ -50,18 +53,18 @@ scene: api: required: true verifierRefs: - - api.team.update + - api.team.update.correlated content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.team.update.correlated] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: contributor-denied + actor: contributor + sceneManifest: ../scenes/negative/edit-contributor.scene.yaml + verifierRefs: [api.team.update.contributor-denied] evidence: required: - playwright_trace diff --git a/guarantees/team/team/scenes/delete-team.scene.yaml b/guarantees/team/team/scenes/delete-team.scene.yaml deleted file mode 100644 index 70e6b421..00000000 --- a/guarantees/team/team/scenes/delete-team.scene.yaml +++ /dev/null @@ -1,130 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team.team.delete-team.016 -title: Delete Team -description: Acceptance scene for guarantee.team.team.delete-team.016. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Delete Team opens the canonical @treeseed/admin destructive confirmation workflow. - - Delete Team exercises a service journey instead of only loading /app/teams/visual-audit-team/delete. - - Delete Team records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Delete Team - action: - goto: /app/teams/visual-audit-team/delete - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Delete Team service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/team/team/scenes/edit-team-settings.scene.yaml b/guarantees/team/team/scenes/edit-team-settings.scene.yaml deleted file mode 100644 index 0b725daa..00000000 --- a/guarantees/team/team/scenes/edit-team-settings.scene.yaml +++ /dev/null @@ -1,130 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team.team.edit-team-settings.014 -title: Edit Team Settings -description: Acceptance scene for guarantee.team.team.edit-team-settings.014. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Edit Team Settings opens the canonical @treeseed/admin full page form workflow. - - Edit Team Settings exercises a service journey instead of only loading /app/teams/visual-audit-team/edit. - - Edit Team Settings records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Edit Team Settings - action: - goto: /app/teams/visual-audit-team/edit - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Edit Team Settings service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/team/team/scenes/switch-active-team.scene.yaml b/guarantees/team/team/scenes/switch-active-team.scene.yaml deleted file mode 100644 index b058801e..00000000 --- a/guarantees/team/team/scenes/switch-active-team.scene.yaml +++ /dev/null @@ -1,130 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team.team.switch-active-team.013 -title: Switch Active Team -description: Acceptance scene for guarantee.team.team.switch-active-team.013. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Switch Active Team opens the canonical @treeseed/admin dashboard read model workflow. - - Switch Active Team exercises a service journey instead of only loading /app/teams. - - Switch Active Team records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Switch Active Team - action: - goto: /app/teams - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect Switch Active Team service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/team/team/scenes/view-team-profile.scene.yaml b/guarantees/team/team/scenes/view-team-profile.scene.yaml deleted file mode 100644 index 11ed2503..00000000 --- a/guarantees/team/team/scenes/view-team-profile.scene.yaml +++ /dev/null @@ -1,130 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team.team.view-team-profile.015 -title: View Team Profile -description: Acceptance scene for guarantee.team.team.view-team-profile.015. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - View Team Profile opens the canonical @treeseed/admin dashboard read model workflow. - - View Team Profile exercises a service journey instead of only loading /app/teams. - - View Team Profile records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: team.primary - kind: team -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open View Team Profile - action: - goto: /app/teams - expect: - urlIncludes: /app/teams - - id: inspect-service-surface - title: Inspect View Team Profile service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/teams -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/team/team/switch-active-team.guarantee.yaml b/guarantees/team/team/switch-active-team.guarantee.yaml index f7cbc5f9..b4492a3b 100644 --- a/guarantees/team/team/switch-active-team.guarantee.yaml +++ b/guarantees/team/team/switch-active-team.guarantee.yaml @@ -18,10 +18,10 @@ actors: - team_owner forbidden: - anonymous_user - - unauthorized_user devices: required: - desktop_chromium + - tablet_chromium - mobile_chromium gates: - core @@ -30,11 +30,14 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - "Journey dependencies must be satisfied: 12" +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.active-selection] scene: required: true - manifest: ./scenes/switch-active-team.scene.yaml + manifest: ../scenes/switch-active-team.scene.yaml + executionKey: admin.team.select-active mode: acceptance: true demo: true @@ -50,7 +53,7 @@ scene: api: required: true verifierRefs: - - api.team.list.owner + - api.team.active.correlated content: required: false verifierRefs: [] @@ -58,10 +61,11 @@ audit: required: false verifierRefs: [] negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember + - id: anonymous-denied + actor: anonymous_user + sceneManifest: ../scenes/negative/anonymous-team-access.scene.yaml + executionKey: admin.team.negative.anonymous-access + verifierRefs: [] evidence: required: - playwright_trace diff --git a/guarantees/team/team/team-management-production-readiness.guarantee.yaml b/guarantees/team/team/team-management-production-readiness.guarantee.yaml new file mode 100644 index 00000000..cfcd8202 --- /dev/null +++ b/guarantees/team/team/team-management-production-readiness.guarantee.yaml @@ -0,0 +1,51 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.team.team.team-management-production-readiness.022 +type: team +subtype: team +journey: Team Management Production Readiness +ownerPackage: "@treeseed/admin" +surface: scene +summary: Fail-closed aggregate proving every team UI capability, actor boundary, device, durable postcondition, audit event, and cleanup contract. +status: active +dependencies: + journeys: [12, 13, 14, 15, 16, 17, 18, 19, 20] + guarantees: + - guarantee.team.team.view-public-team-profile.021 +actors: + allowed: [release_operator] + forbidden: [] +devices: + required: [desktop_chromium, mobile_chromium] +gates: [core, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: + - Every required feature guarantee must be active and pass against the same current source closure. +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [] +api: + required: true + verifierRefs: + - admin.team.production-readiness + - admin.team.ui-contracts + - api.team.lifecycle-contracts + - sdk.team.ui-evidence-trust +content: + required: false + verifierRefs: [] +audit: + required: false + verifierRefs: [] +negativeCases: + - id: stale-or-mismatched-evidence-denied + verifierRefs: [sdk.team.ui-evidence-trust] + notes: + - Device mismatch, source drift, blocked requirements, and copied aggregate status must fail closed. +evidence: + required: [execution_graph, api_verification_log, cleanup_report] +notes: + - Fails closed unless every required team guarantee, feature contract, current-source verifier, and cleanup check passes. +run: + timeoutSeconds: 900 + requiredForRelease: true diff --git a/guarantees/team/team/view-public-team-profile.guarantee.yaml b/guarantees/team/team/view-public-team-profile.guarantee.yaml new file mode 100644 index 00000000..db9bf8ff --- /dev/null +++ b/guarantees/team/team/view-public-team-profile.guarantee.yaml @@ -0,0 +1,57 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.team.team.view-public-team-profile.021 +type: team +subtype: team +journey: View Public Team Profile +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: Expose active team identity and explicitly public reusable knowledge anonymously for public teams and to authenticated members for private teams, while redacting private membership and operational context. +status: active +dependencies: + journeys: [14] + guarantees: [guarantee.team.team.edit-team-settings.014] +actors: + allowed: [anonymous_user, team_member] + forbidden: [] +devices: + required: [desktop_chromium, tablet_chromium, mobile_chromium] +gates: [core, release] +preconditions: + fixtures: [integrated_treeseed_project] + notes: [The owning team identity must already exist.] +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.public-profile] +scene: + required: true + manifest: ../scenes/view-public-team-profile.scene.yaml + executionKey: admin.team.public-profile + mode: { acceptance: true, demo: true, training: true } + entryRoute: /t/[name] + componentContract: anonymous knowledge profile + expectedEvidence: [playwright_trace, scene_video, screenshot_on_failure, console_log, network_log] +api: + required: true + verifierRefs: [api.team.public-profile.correlated] +content: + required: false + verifierRefs: [] +audit: + required: false + verifierRefs: [] +negativeCases: + - id: archived-not-found + actor: anonymous_user + verifierRefs: [api.team.public-profile.archived-not-found] + - id: private-anonymous-not-found + actor: anonymous_user + verifierRefs: [api.team.public-profile.private-member-access] +evidence: + required: [playwright_trace, scene_video, api_verification_log] +notes: + - This supplemental guarantee intentionally has no CSV journey index. + - Public projects, templates, knowledge packs, and their publication trail are explicit public projections, never private operational aggregates. + - Private active profiles remain hidden anonymously but are available to authenticated members, including after archive and restore. +run: + timeoutSeconds: 300 + requiredForRelease: true diff --git a/guarantees/team/team/view-team-overview.guarantee.yaml b/guarantees/team/team/view-team-overview.guarantee.yaml new file mode 100644 index 00000000..2f913230 --- /dev/null +++ b/guarantees/team/team/view-team-overview.guarantee.yaml @@ -0,0 +1,86 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.team.team.view-team-overview.015 +journeyIndex: 15 +type: team +subtype: team +journey: View Team Overview +ownerPackage: "@treeseed/admin" +summary: Display the authenticated operational team overview and preserve access-checked team navigation when a member opens the public profile. +status: active +dependencies: + journeys: + - 14 + guarantees: + - guarantee.team.team.edit-team-settings.014 +actors: + allowed: + - team_member + forbidden: + - anonymous_user + - non_member +devices: + required: + - desktop_chromium + - tablet_chromium + - mobile_chromium +gates: + - core + - release +preconditions: + fixtures: + - integrated_treeseed_project + notes: + - "Journey dependencies must be satisfied: 12" +scene: + required: true + manifest: ../scenes/view-team-overview.scene.yaml + executionKey: admin.team.overview + mode: + acceptance: true + demo: true + training: true + entryRoute: /app/teams/[teamId] + componentContract: authenticated operational team overview + expectedEvidence: + - playwright_trace + - scene_video + - screenshot_on_failure + - console_log + - network_log +api: + required: true + verifierRefs: + - api.team.overview.correlated +content: + required: false + verifierRefs: [] +audit: + required: false + verifierRefs: [] +negativeCases: + - id: anonymous-denied + actor: anonymous_user + sceneManifest: ../scenes/negative/anonymous-team-access.scene.yaml + executionKey: admin.team.negative.anonymous-access + verifierRefs: [api.team.overview.anonymous-denied] + - id: non-member-denied + actor: non_member + sceneManifest: ../scenes/negative/overview-nonmember.scene.yaml + executionKey: admin.team.negative.overview-nonmember + verifierRefs: [api.team.overview.nonmember-denied] +evidence: + required: + - playwright_trace + - scene_video + - api_verification_log + optional: + - mailpit_message +notes: + - Public identity is covered separately by guarantee.team.team.view-public-team-profile.021. +uiFeature: + contract: ../team-management.ui-feature.yaml + capabilities: [team.collection, team.operational-overview, team.public-profile] +surface: admin-ui +run: + timeoutSeconds: 300 + requiredForRelease: true diff --git a/guarantees/team/team/view-team-profile.guarantee.yaml b/guarantees/team/team/view-team-profile.guarantee.yaml deleted file mode 100644 index 8980d274..00000000 --- a/guarantees/team/team/view-team-profile.guarantee.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.team.team.view-team-profile.015 -journeyIndex: 15 -type: team -subtype: team -journey: View Team Profile -ownerPackage: "@treeseed/admin" -summary: Display team metadata members projects allocation sets and operational status; should aggregate through API read models. -status: active -dependencies: - journeys: - - 12 - guarantees: - - guarantee.team.team.create-team.012 -actors: - allowed: - - team_admin - - team_owner - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - - "Journey dependencies must be satisfied: 12" -scene: - required: true - manifest: ./scenes/view-team-profile.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/teams - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - api.team.profile -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] -negativeCases: - - id: non-member-denied - actor: non_member - verifierRefs: - - api.team.members.nonmember -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - optional: - - mailpit_message -notes: - - Display team metadata members projects allocation sets and operational status; should aggregate through API read models. -surface: admin-ui -run: - timeoutSeconds: 300 - requiredForRelease: true diff --git a/guarantees/user/account/delete-user.guarantee.yaml b/guarantees/user/account/delete-user.guarantee.yaml index 3de8964f..7039df79 100644 --- a/guarantees/user/account/delete-user.guarantee.yaml +++ b/guarantees/user/account/delete-user.guarantee.yaml @@ -8,10 +8,9 @@ ownerPackage: "@treeseed/admin" summary: Perform a destructive account removal with ownership and membership checks; needs policy around teams projects content and provider-owned auth records. status: active dependencies: - journeys: - - 4 + journeys: [] guarantees: - - guarantee.user.auth.user-login.004 + - guarantee.user.auth.user-logout.005 actors: allowed: - verified_user @@ -29,16 +28,16 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - - "Journey dependencies must be satisfied: 4" + - Team deletion and logout must complete before final account deletion. scene: required: true manifest: ./scenes/delete-user.scene.yaml + executionKey: admin.account.delete mode: acceptance: true demo: true training: true - entryRoute: /app/account + entryRoute: /app/account/delete componentContract: destructive-confirmation service journey expectedEvidence: - playwright_trace @@ -54,8 +53,8 @@ content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.auth.lifecycle.audit] negativeCases: - id: anonymous-denied actor: anonymous_user diff --git a/guarantees/user/account/edit-account-settings.guarantee.yaml b/guarantees/user/account/edit-account-settings.guarantee.yaml index 82bfa283..eedda023 100644 --- a/guarantees/user/account/edit-account-settings.guarantee.yaml +++ b/guarantees/user/account/edit-account-settings.guarantee.yaml @@ -5,7 +5,7 @@ type: user subtype: account journey: Edit Account Settings ownerPackage: "@treeseed/admin" -summary: Edit user profile preferences owned by the admin/account surface; persistence should live in the API or auth metadata and not in root Market-only state. +summary: Edit user identity, verify additional account emails, and persist the account-wide time zone used by every UI timestamp. status: active dependencies: journeys: @@ -29,11 +29,12 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. + - The onboarding identity supplies the stable username used by the anonymous profile proof. - "Journey dependencies must be satisfied: 4" scene: required: true manifest: ./scenes/edit-account-settings.scene.yaml + executionKey: admin.account.edit-profile mode: acceptance: true demo: true @@ -50,12 +51,15 @@ api: required: true verifierRefs: - api.auth.profile.update + - api.auth.account-preferences + - api.auth.email.lifecycle content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: + - api.auth.lifecycle.audit negativeCases: - id: anonymous-denied actor: anonymous_user @@ -69,7 +73,7 @@ evidence: optional: - mailpit_message notes: - - Edit user profile preferences owned by the admin/account surface; persistence should live in the API or auth metadata and not in root Market-only state. + - Account identity, additional verified emails, and the selected IANA time zone persist through API-owned records; notification delivery consumes the same account time zone. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/user/account/manage-api-tokens.guarantee.yaml b/guarantees/user/account/manage-api-tokens.guarantee.yaml deleted file mode 100644 index d9eea17b..00000000 --- a/guarantees/user/account/manage-api-tokens.guarantee.yaml +++ /dev/null @@ -1,76 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.user.account.manage-api-tokens.094 -journeyIndex: 94 -type: user -subtype: account -journey: Manage API Tokens -ownerPackage: "@treeseed/admin" -summary: Create rotate and revoke user or automation tokens where supported; should be separate from provider capacity keys. -status: active -dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 -actors: - allowed: - - verified_user - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - - "Journey dependencies must be satisfied: 4" -scene: - required: true - manifest: ./scenes/manage-api-tokens.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/account - componentContract: record-operations service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - api.auth.sessions -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] -negativeCases: - - id: anonymous-denied - actor: anonymous_user - verifierRefs: - - api.auth.me.requires-user -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - optional: - - mailpit_message -notes: - - Create rotate and revoke user or automation tokens where supported; should be separate from provider capacity keys. -surface: admin-ui -run: - timeoutSeconds: 300 - requiredForRelease: true diff --git a/guarantees/user/account/manage-appearance.guarantee.yaml b/guarantees/user/account/manage-appearance.guarantee.yaml index 5bd7c6de..8e012748 100644 --- a/guarantees/user/account/manage-appearance.guarantee.yaml +++ b/guarantees/user/account/manage-appearance.guarantee.yaml @@ -5,7 +5,7 @@ type: user subtype: account journey: Manage Appearance ownerPackage: "@treeseed/admin" -summary: Set theme and interface preferences for the admin shell; should use reusable UI/theme tokens and persist per user where available. +summary: Set persistent application and independently scoped content-workspace appearance preferences with reusable accessible UI theme tokens. status: active dependencies: journeys: @@ -29,16 +29,17 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. + - The authenticated account has access to personal theme creation and shell selection. - "Journey dependencies must be satisfied: 4" scene: required: true manifest: ./scenes/manage-appearance.scene.yaml + executionKey: admin.account.appearance mode: acceptance: true demo: true training: true - entryRoute: /app/account + entryRoute: /app/account/appearance componentContract: record-modal-form service journey expectedEvidence: - playwright_trace @@ -69,7 +70,8 @@ evidence: optional: - mailpit_message notes: - - Set theme and interface preferences for the admin shell; should use reusable UI/theme tokens and persist per user where available. + - Application appearance and the optional content workspace scheme and mode persist per user. + - The content workspace palette applies to ControlSurface and content overlays without changing persistent shell utilities or fading readable tokens. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/user/account/manage-notifications.guarantee.yaml b/guarantees/user/account/manage-notifications.guarantee.yaml index 0e0e0083..19dd897b 100644 --- a/guarantees/user/account/manage-notifications.guarantee.yaml +++ b/guarantees/user/account/manage-notifications.guarantee.yaml @@ -5,71 +5,43 @@ type: user subtype: account journey: Manage Notifications ownerPackage: "@treeseed/admin" -summary: Manage user notification preferences for Treeseed events; likely needs a durable API model before the UI can be more than local settings. +summary: Configure global content-type notification preferences, exact per-project replacements, and one email cadence without weakening project authorization. status: active dependencies: - journeys: - - 4 - guarantees: - - guarantee.user.auth.user-login.004 + journeys: [4] + guarantees: [guarantee.user.auth.user-login.004] actors: - allowed: - - verified_user - forbidden: - - anonymous_user - - unauthorized_user + allowed: [verified_user] + forbidden: [anonymous_user, unauthorized_user] devices: - required: - - desktop_chromium - - mobile_chromium -gates: - - core - - release + required: [desktop_chromium, mobile_chromium] +gates: [core] preconditions: - fixtures: - - integrated_treeseed_project + fixtures: [integrated_treeseed_project] notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. - - "Journey dependencies must be satisfied: 4" + - Keep planned until the UI scene and API verifier produce repeatable local database and delivery evidence. scene: required: true manifest: ./scenes/manage-notifications.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/account - componentContract: full-page-form service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log + executionKey: admin.account.notifications + mode: { acceptance: true, demo: true, training: true } + entryRoute: /app/account/notifications + componentContract: notification-preference-panel + expectedEvidence: [playwright_trace, scene_video, screenshot_on_failure, console_log, network_log] api: required: true - verifierRefs: - - api.auth.me.site-admin -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] + verifierRefs: [api.auth.notifications] +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } negativeCases: - id: anonymous-denied actor: anonymous_user - verifierRefs: - - api.auth.me.requires-user + verifierRefs: [api.auth.me.requires-user] evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - optional: - - mailpit_message + required: [playwright_trace, scene_video, api_verification_log] + optional: [mailpit_message] notes: - - Manage user notification preferences for Treeseed events; likely needs a durable API model before the UI can be more than local settings. + - Proves replacement inheritance, project authorization filtering, immediate in-app visibility, and independent email cadence. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/user/account/manage-sessions.guarantee.yaml b/guarantees/user/account/manage-sessions.guarantee.yaml index 7229dabb..1d1870d0 100644 --- a/guarantees/user/account/manage-sessions.guarantee.yaml +++ b/guarantees/user/account/manage-sessions.guarantee.yaml @@ -5,7 +5,7 @@ type: user subtype: account journey: Manage Sessions ownerPackage: "@treeseed/admin" -summary: List and revoke active sessions through the auth/session facade; this may be missing if the selected auth provider does not expose session management yet. +summary: List active sessions with source IP and account-time-zone-aware activity dates, revoke a non-current session, and preserve the current session through the auth/session facade. status: active dependencies: journeys: @@ -29,16 +29,17 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. + - The acceptance fixture supplies a third revocable session while preserving both journey sessions. - "Journey dependencies must be satisfied: 4" scene: required: true manifest: ./scenes/manage-sessions.scene.yaml + executionKey: admin.account.sessions mode: acceptance: true demo: true training: true - entryRoute: /app/account + entryRoute: /app/account/sessions componentContract: record-operations service journey expectedEvidence: - playwright_trace @@ -54,8 +55,8 @@ content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.auth.lifecycle.audit] negativeCases: - id: anonymous-denied actor: anonymous_user @@ -69,7 +70,7 @@ evidence: optional: - mailpit_message notes: - - List and revoke active sessions through the auth/session facade; this may be missing if the selected auth provider does not expose session management yet. + - Session metadata records the trusted forwarded client address at authentication and presents an explicit fallback when an address was unavailable. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/user/account/scenes/delete-user.scene.yaml b/guarantees/user/account/scenes/delete-user.scene.yaml index d79eb092..8ed32347 100644 --- a/guarantees/user/account/scenes/delete-user.scene.yaml +++ b/guarantees/user/account/scenes/delete-user.scene.yaml @@ -11,11 +11,18 @@ journey: - Delete User opens the canonical @treeseed/admin destructive confirmation workflow. - Delete User exercises a service journey instead of only loading /app/account. - Delete User records reviewable evidence for the visible result before activation. - minimumSteps: 2 + minimumSteps: 10 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user + - key: auth.onboarding-session + kind: browser-storage + - key: auth.logged-out + kind: marker + - key: team.deleted + kind: marker + producesState: + - key: account.deleted + kind: marker mode: test: true demo: true @@ -80,15 +87,97 @@ workflow: - id: open-entry-route title: Open Delete User action: - goto: /app/account + goto: /app/account/delete expect: - urlIncludes: /app/account - - id: inspect-service-surface - title: Inspect Delete User service surface + urlIncludes: /app/account/delete + visible: + - scene: account-delete + - id: enter-invalid-confirmation + title: Enter an invalid deletion confirmation action: - keyboard: Tab + fill: + role: textbox + name: Type "DELETE MY ACCOUNT" + value: DELETE expect: - urlIncludes: /app/account + text: Delete account + - id: enter-current-password + title: Reauthenticate account deletion + action: + fill: + css: "#currentPassword" + internal: true + value: TreeSeedGuaranteeReset123! + expect: + text: Current password + - id: reject-invalid-deletion + title: Reject invalid account deletion + action: + click: + role: button + name: Delete my account + expect: + urlIncludes: /app/account/delete + text: DELETE MY ACCOUNT + clientErrorSourceIncludes: /app/account/delete + - id: enter-valid-confirmation + title: Enter the exact deletion confirmation + action: + fill: + css: "#confirmation" + internal: true + value: DELETE MY ACCOUNT + expect: + text: Delete account + - id: reauthenticate-valid-deletion + title: Reauthenticate the valid deletion request + action: + fill: + css: "#currentPassword" + internal: true + value: TreeSeedGuaranteeReset123! + expect: + text: Current password + - id: delete-account + title: Permanently delete the account + action: + click: + role: button + name: Delete my account + expect: + urlIncludes: /auth/sign-in + visible: + - role: heading + name: Sign in + - id: enter-deleted-authorization-email + title: Enter the deleted identity at the sign-in boundary + action: + fill: + role: textbox + name: Email or username + value: guarantee-{{runId}}-{{deviceId}}@treeseed.local + expect: + urlIncludes: /auth/sign-in + - id: enter-deleted-authorization-password + title: Enter the deleted credential at the sign-in boundary + action: + fill: + css: "#password" + internal: true + value: TreeSeedGuaranteeReset123! + expect: + urlIncludes: /auth/sign-in + - id: reject-deleted-account-authorization + title: Reject sign-in for the deleted identity + action: + click: + role: button + name: Sign in + expect: + urlIncludes: /auth/sign-in + visible: + - role: button + name: Sign in chapters: [] overlays: [] diagrams: [] diff --git a/guarantees/user/account/scenes/edit-account-settings.scene.yaml b/guarantees/user/account/scenes/edit-account-settings.scene.yaml index 1521677f..25b556a5 100644 --- a/guarantees/user/account/scenes/edit-account-settings.scene.yaml +++ b/guarantees/user/account/scenes/edit-account-settings.scene.yaml @@ -10,12 +10,16 @@ journey: proves: - Edit Account Settings opens the canonical @treeseed/admin full page form workflow. - Edit Account Settings exercises a service journey instead of only loading /app/account. + - A signed-in user can add an email, consume the delivered confirmation link, and observe its verified state. - Edit Account Settings records reviewable evidence for the visible result before activation. - minimumSteps: 2 + minimumSteps: 7 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user + - key: auth.primary-session + kind: browser-storage + producesState: + - key: account.profile-updated + kind: marker mode: test: true demo: true @@ -83,12 +87,152 @@ workflow: goto: /app/account expect: urlIncludes: /app/account - - id: inspect-service-surface - title: Inspect Edit Account Settings service surface + visible: + - scene: account-identity + - css: '[data-page-header-owner="content"] .ts-page-header' + internal: true + notVisible: + - css: '[data-page-header-owner="content"] > .ts-product-shell__body .ts-control-surface > .ts-control-surface__header' + internal: true + - id: open-account-help + title: Open account identity guidance without leaving the form action: - keyboard: Tab + click: { css: '.ts-template--settings > .ts-page-header button[data-ts-help-knowledge-page-id="account.identity"]', internal: true } expect: urlIncludes: /app/account + visible: + - { css: '[data-ts-help-dialog][open]', internal: true } + text: Public identity + - id: close-account-help + title: Close account guidance and restore focus + action: + click: { role: button, name: Close help } + expect: + notVisible: + - { css: '[data-ts-help-dialog][open]', internal: true } + focused: { css: '.ts-template--settings > .ts-page-header button[data-ts-help-knowledge-page-id="account.identity"]', internal: true } + - id: edit-first-name + title: Edit the public first name + action: + fill: + role: textbox + name: First name + value: Guarantee + expect: + text: Public profile + - id: edit-last-name + title: Edit the public last name + action: + fill: + role: textbox + name: Last name + value: "{{deviceId}}" + expect: + text: Public profile + - id: save-profile + title: Save account identity + action: + click: + role: button + name: Save identity + expect: + urlIncludes: /app/account + text: Identity saved. + visible: + - css: '[data-ts-toast-id][data-tone="success"]' + internal: true + - id: reload-profile + title: Reload the durable profile + action: + goto: /app/account + expect: + visible: + - scene: account-identity + - scene: account-time-zone + - id: select-time-zone + title: Select an account-wide display time zone + action: + select: + role: combobox + name: Display time zone + label: America / New York + expect: + text: Dates and times across the application use this time zone. + - id: save-time-zone + title: Save the display time zone without leaving account settings + action: + click: + role: button + name: Save time zone + expect: + urlIncludes: /app/account + text: Time zone saved. + visible: + - css: '[data-ts-toast-id][data-tone="success"]' + internal: true + - id: reload-time-zone + title: Reload the durable account time zone + action: + goto: /app/account + expect: + urlIncludes: /app/account + visible: + - css: '[data-scene="account-time-zone"][data-time-zone="America/New_York"]' + internal: true + - id: enter-additional-email + title: Enter an additional account email + action: + fill: + role: textbox + name: Add email + value: guarantee-extra-{{runId}}-{{deviceId}}@treeseed.local + expect: + visible: + - scene: account-identity + - id: send-additional-email-verification + title: Add the pending email and send its verification message + action: + click: + role: button + name: Add and verify + expect: + urlIncludes: /app/account + text: Verification email sent. + visible: + - css: '[data-ts-toast-id][data-tone="success"]' + internal: true + - css: '[data-account-email="guarantee-extra-{{runId}}-{{deviceId}}@treeseed.local"][data-account-email-status="pending"]' + internal: true + - id: confirm-additional-email + title: Confirm the additional email while the account session remains active + action: + mailpitConfirmLatest: + mailpitUrl: http://127.0.0.1:8025 + email: guarantee-extra-{{runId}}-{{deviceId}}@treeseed.local + subjectIncludes: Confirm your TreeSeed email + displayInboxSeconds: 1 + displayMessageSeconds: 1 + expect: + urlIncludes: /auth/confirm-email + text: Confirm your email + - id: approve-additional-email-confirmation + title: Explicitly confirm the one-use additional-email token + action: + click: + role: button + name: Confirm email + expect: + urlIncludes: /auth/confirm-email + text: Email confirmed + - id: reload-confirmed-additional-email + title: Return to account identity and verify the confirmed email + action: + goto: /app/account + expect: + urlIncludes: /app/account + visible: + - css: '[data-account-email="guarantee-extra-{{runId}}-{{deviceId}}@treeseed.local"][data-account-email-status="verified"]' + internal: true chapters: [] overlays: [] diagrams: [] diff --git a/guarantees/user/account/scenes/manage-api-tokens.scene.yaml b/guarantees/user/account/scenes/manage-api-tokens.scene.yaml deleted file mode 100644 index a9f2d575..00000000 --- a/guarantees/user/account/scenes/manage-api-tokens.scene.yaml +++ /dev/null @@ -1,128 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: user.account.manage-api-tokens.094 -title: Manage API Tokens -description: Acceptance scene for guarantee.user.account.manage-api-tokens.094. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Manage API Tokens opens the canonical @treeseed/admin dashboard read model workflow. - - Manage API Tokens exercises a service journey instead of only loading /app/account. - - Manage API Tokens records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Manage API Tokens - action: - goto: /app/account - expect: - urlIncludes: /app/account - - id: inspect-service-surface - title: Inspect Manage API Tokens service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/account -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/user/account/scenes/manage-appearance.scene.yaml b/guarantees/user/account/scenes/manage-appearance.scene.yaml index e6d4764b..5d218b52 100644 --- a/guarantees/user/account/scenes/manage-appearance.scene.yaml +++ b/guarantees/user/account/scenes/manage-appearance.scene.yaml @@ -11,11 +11,14 @@ journey: - Manage Appearance opens the canonical @treeseed/admin dashboard read model workflow. - Manage Appearance exercises a service journey instead of only loading /app/account. - Manage Appearance records reviewable evidence for the visible result before activation. - minimumSteps: 2 + minimumSteps: 8 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user + - key: auth.primary-session + kind: browser-storage + producesState: + - key: account.appearance-updated + kind: marker mode: test: true demo: true @@ -80,15 +83,88 @@ workflow: - id: open-entry-route title: Open Manage Appearance action: - goto: /app/account + goto: /app/account/appearance expect: - urlIncludes: /app/account - - id: inspect-service-surface - title: Inspect Manage Appearance service surface + urlIncludes: /app/account/appearance + visible: + - scene: account-appearance + - css: '[data-built-in-theme-table]' + internal: true + - id: open-theme-dialog + title: Open personal theme creation action: - keyboard: Tab + click: + role: button + name: Create theme expect: - urlIncludes: /app/account + text: Create a personal theme + - id: name-personal-theme + title: Name the personal theme + action: + fill: + role: textbox + name: Theme name + value: Guarantee {{runShort}} {{deviceId}} + expect: + visible: + - css: "[data-personal-theme-builder] [data-personal-theme-base]" + internal: true + - id: change-personal-theme-base + title: Seed the custom palette from another built-in theme + action: + select: + role: combobox + name: Base theme + label: Cedar Clay + expect: + visible: + - css: '[data-personal-theme-builder][data-theme-palette-source="cedar"] [data-theme-color-mode="light"][data-theme-color-key="accent"][data-theme-color-value="#b86b3c"]' + internal: true + - id: create-personal-theme + title: Create the personal theme + action: + click: + testId: create-personal-theme-submit + expect: + urlIncludes: /app/account/appearance + text: Theme saved. + visible: + - css: '[data-ts-toast-id][data-tone="success"]' + internal: true + - id: reload-personal-theme + title: Reload the personal theme collection + action: + goto: /app/account/appearance + expect: + visible: + - scene: account-appearance + - id: open-appearance-selector + title: Open the application appearance selector + action: + click: + css: '[data-testid="appearance-menu-trigger"]:visible' + internal: true + expect: + text: Color scheme + - id: activate-personal-theme + title: Select the personal theme from the application header + action: + select: + role: combobox + name: Color scheme + label: Guarantee {{runShort}} {{deviceId}} + settleNavigation: true + expect: + urlIncludes: /app/account/appearance + - id: reload-active-personal-theme + title: Reload and prove the active personal theme is durable + action: + goto: /app/account/appearance + expect: + urlIncludes: /app/account/appearance + visible: + - css: '[data-active-personal-theme-name="Guarantee {{runShort}} {{deviceId}}"]' + internal: true chapters: [] overlays: [] diagrams: [] diff --git a/guarantees/user/account/scenes/manage-notifications.scene.yaml b/guarantees/user/account/scenes/manage-notifications.scene.yaml index 70ebce47..2a65187e 100644 --- a/guarantees/user/account/scenes/manage-notifications.scene.yaml +++ b/guarantees/user/account/scenes/manage-notifications.scene.yaml @@ -1,128 +1,103 @@ schemaVersion: treeseed.scene/v1 id: user.account.manage-notifications.008 title: Manage Notifications -description: Acceptance scene for guarantee.user.account.manage-notifications.008. -audience: - - operator - - evaluator +description: Configure canonical account notification preferences and capture reviewable evidence. +audience: [operator, evaluator] journey: kind: service proves: - - Manage Notifications opens the canonical @treeseed/admin dashboard read model workflow. - - Manage Notifications exercises a service journey instead of only loading /app/account. - - Manage Notifications records reviewable evidence for the visible result before activation. - minimumSteps: 2 + - Notification cadence is independent from immediate in-app visibility. + - Global content types apply unless an authorized project exact-replacement override is selected. + - The notification preference implementation is the shared UI-package component. + minimumSteps: 4 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true + - { key: auth.primary-session, kind: browser-storage } + producesState: + - { key: account.notifications-updated, kind: marker } +mode: { test: true, demo: true, training: true } target: app: market environment: local baseUrl: auto browser: chromium - viewport: - width: 1600 - height: 900 + viewport: { width: 1600, height: 900 } devices: defaultProfile: desktop_chromium profiles: - id: desktop_chromium title: Desktop Chromium orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 + viewport: { width: 1600, height: 900 } + video: { width: 1600, height: 900 } + output: { width: 1920, height: 1080 } deviceScaleFactor: 1 isMobile: false hasTouch: false - id: mobile_chromium title: Mobile Chromium orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 + viewport: { width: 390, height: 844 } + video: { width: 390, height: 844 } + output: { width: 390, height: 844 } deviceScaleFactor: 2 isMobile: true hasTouch: true setup: - dev: - required: true - reuseExisting: true - auth: - role: owner - required: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true + dev: { required: true, reuseExisting: true } + auth: { role: owner, required: true } +artifacts: { trace: true, video: true, screenshots: true, console: true, network: true, timeline: true, appLogs: true } workflow: - - id: open-entry-route - title: Open Manage Notifications - action: - goto: /app/account + - id: open-notifications + title: Open notification preferences + action: { goto: /app/account/notifications } + expect: { urlIncludes: /app/account/notifications, visible: [{ scene: account-notifications }] } + - id: select-weekly + title: Select weekly email cadence + action: { click: { role: radio, name: Weekly } } + expect: { text: In-app notifications remain immediate. } + - id: select-questions + title: Select questions globally + action: { click: { role: checkbox, name: Questions } } expect: - urlIncludes: /app/account - - id: inspect-service-surface - title: Inspect Manage Notifications service surface - action: - keyboard: Tab + text: These choices apply to every project + visible: + - css: '[data-notification-content-choices][data-orientation="vertical"][aria-label="All-project content types"]' + internal: true + - id: save-preferences + title: Save notification preferences + action: { click: { role: button, name: Save notification preferences } } expect: - urlIncludes: /app/account + urlIncludes: /app/account/notifications + text: Notification preferences saved. + visible: + - css: '[data-ts-toast-id][data-tone="success"]' + internal: true + - id: reload-preferences + title: Reload persisted notification preferences + action: { goto: /app/account/notifications } + expect: + urlIncludes: /app/account/notifications + text: Weekly + visible: + - css: '[aria-label="All-project content types"] input[name="globalContentTypes"][value="questions"]:checked' + internal: true chapters: [] overlays: [] diagrams: [] render: remotion: composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 + output: { format: mp4, fps: 30, resolution: { width: 1920, height: 1080 } } capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 + viewport: { width: 1600, height: 900 } + video: { width: 1600, height: 900 } evidenceFit: fixed-browser runtime: mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false + timeouts: { sceneSeconds: 300, chapterSeconds: 120, stepSeconds: 60 } + checkpoints: { enabled: true, defaultResumable: true, everyStep: true } + progress: { heartbeatSeconds: 15 } + failure: { continueOnFailure: false } training: {} -visualAudit: - enabled: false +visualAudit: { enabled: false } diff --git a/guarantees/user/account/scenes/manage-sessions.scene.yaml b/guarantees/user/account/scenes/manage-sessions.scene.yaml index d68decf5..34d95d13 100644 --- a/guarantees/user/account/scenes/manage-sessions.scene.yaml +++ b/guarantees/user/account/scenes/manage-sessions.scene.yaml @@ -11,11 +11,14 @@ journey: - Manage Sessions opens the canonical @treeseed/admin dashboard read model workflow. - Manage Sessions exercises a service journey instead of only loading /app/account. - Manage Sessions records reviewable evidence for the visible result before activation. - minimumSteps: 2 + minimumSteps: 5 requiresInteractiveAction: true consumesState: - - key: auth.owner - kind: user + - key: auth.primary-session + kind: browser-storage + producesState: + - key: account.sessions-reviewed + kind: marker mode: test: true demo: true @@ -80,15 +83,70 @@ workflow: - id: open-entry-route title: Open Manage Sessions action: - goto: /app/account + goto: /app/account/sessions expect: - urlIncludes: /app/account - - id: inspect-service-surface - title: Inspect Manage Sessions service surface + urlIncludes: /app/account/sessions + visible: + - scene: account-sessions + text: Current session + - id: create-revocable-session + title: Create an additional session owned by this run action: - keyboard: Tab + createBrowserSession: + identifier: guarantee-{{runId}}-{{deviceId}}@treeseed.local + password: TreeSeedGuaranteeReset123! + userAgent: Treeseed Guarantee Revocable Session + clientIp: 198.51.100.27 expect: - urlIncludes: /app/account + urlIncludes: /app/account/sessions + text: Current session + - id: reload-session-list + title: Load the run-owned revocable session + action: + goto: /app/account/sessions + expect: + visible: + - scene: account-sessions + text: Revoke session + - id: verify-session-metadata-and-pretty-time + title: Verify the additional session and formatted time without trusting a spoofed edge address + action: + goto: /app/account/sessions + expect: + notText: T00:00:00.000Z + visible: + - css: '[data-session-entry]:has(button:has-text("Revoke session")) [data-session-ip]' + internal: true + - css: '[data-session-entry]:has(button:has-text("Revoke session")) .account-session-signed-in' + internal: true + - id: reject-current-session-revocation + title: Prove no current-session revoke control is exposed + action: + goto: /app/account/sessions + expect: + urlIncludes: /app/account/sessions + text: Current session + notText: Revoke current session + - id: revoke-extra-session + title: Revoke the additional non-current session + action: + click: + css: '[data-session-entry]:has(button:has-text("Revoke session")) button:has-text("Revoke session")' + internal: true + expect: + urlIncludes: /app/account/sessions + text: Session revoked. + visible: + - css: '[data-ts-toast-id][data-tone="success"]' + internal: true + - id: verify-revoked-session + title: Verify the revoked session remains observable + action: + goto: /app/account/sessions + expect: + visible: + - scene: account-sessions + text: Revoked chapters: [] overlays: [] diagrams: [] diff --git a/guarantees/user/account/scenes/view-user-profile.scene.yaml b/guarantees/user/account/scenes/view-user-profile.scene.yaml index 7f356640..69fe6672 100644 --- a/guarantees/user/account/scenes/view-user-profile.scene.yaml +++ b/guarantees/user/account/scenes/view-user-profile.scene.yaml @@ -8,11 +8,16 @@ audience: journey: kind: service proves: - - View User Profile opens the canonical @treeseed/admin dashboard read model workflow. - - View User Profile exercises a service journey instead of only loading /app/account. + - View User Profile opens the public @treeseed/admin knowledge profile. + - View User Profile separates explicitly attributed public work from private membership context. - View User Profile records reviewable evidence for the visible result before activation. - minimumSteps: 2 + minimumSteps: 3 requiresInteractiveAction: true + consumesState: + - key: auth.primary-session + kind: browser-storage + - key: account.profile-updated + kind: marker mode: test: true demo: true @@ -62,6 +67,9 @@ setup: dev: required: true reuseExisting: true + auth: + role: owner + required: true artifacts: trace: true video: true @@ -72,17 +80,44 @@ artifacts: appLogs: true workflow: - id: open-entry-route - title: Open View User Profile + title: Open the anonymous public profile action: - goto: /app/account + goto: /u/g-{{runShort}}-{{deviceId}} expect: - urlIncludes: /app/account - - id: inspect-service-surface - title: Inspect View User Profile service surface + urlIncludes: /u/g- + text: Public contributions + visible: + - scene: knowledge.profile + - scene: knowledge.identity + - scene: knowledge.activity + - scene: account.navigation + - id: verify-private-data-redacted + title: Verify private identity data is redacted + action: + goto: /u/g-{{runShort}}-{{deviceId}} + expect: + notText: guarantee-{{runId}}-{{deviceId}}@treeseed.local + - id: verify-memberships-redacted + title: Verify memberships are not published + action: + goto: /u/g-{{runShort}}-{{deviceId}} + expect: + notText: Memberships + - id: verify-roles-redacted + title: Verify roles are not published + action: + goto: /u/g-{{runShort}}-{{deviceId}} + expect: + notText: Roles + - id: open-account-management + title: Open account management through the canonical profile tabs action: - keyboard: Tab + click: + role: link + name: Identity expect: urlIncludes: /app/account + text: Account identity chapters: [] overlays: [] diagrams: [] diff --git a/guarantees/user/account/view-user-profile.guarantee.yaml b/guarantees/user/account/view-user-profile.guarantee.yaml index 5bd516a1..b7b935da 100644 --- a/guarantees/user/account/view-user-profile.guarantee.yaml +++ b/guarantees/user/account/view-user-profile.guarantee.yaml @@ -5,18 +5,18 @@ type: user subtype: account journey: View User Profile ownerPackage: "@treeseed/admin" -summary: Show identity and account metadata plus team/project memberships; current architecture should read through public admin/API facades. +summary: Show public user identity, expertise, and explicitly attributed reusable knowledge, with canonical account tabs only for the owning signed-in user. status: active dependencies: journeys: - - 1 + - 6 guarantees: - - guarantee.user.auth.register-user.001 + - guarantee.user.account.edit-account-settings.006 actors: allowed: - verified_user - forbidden: - anonymous_user + forbidden: - unauthorized_user devices: required: @@ -29,17 +29,19 @@ preconditions: fixtures: - integrated_treeseed_project notes: - - Planned by guarantee journey audit: the referenced UI route/behavior is not implemented as an executable service journey yet. + - The authenticated owning user sees canonical account-management tabs above the profile. + - Anonymous redaction remains covered by the public API verifier. - "Journey dependencies must be satisfied: 1" scene: required: true manifest: ./scenes/view-user-profile.scene.yaml + executionKey: admin.account.public-profile mode: acceptance: true demo: true training: true - entryRoute: /app/account - componentContract: dashboard/read-model service journey + entryRoute: /u/[username] + componentContract: public knowledge profile expectedEvidence: - playwright_trace - scene_video @@ -49,7 +51,7 @@ scene: api: required: true verifierRefs: - - api.auth.me.site-admin + - api.auth.public-knowledge-profile content: required: false verifierRefs: [] @@ -57,10 +59,10 @@ audit: required: false verifierRefs: [] negativeCases: - - id: anonymous-denied + - id: private-context-redacted actor: anonymous_user verifierRefs: - - api.auth.me.requires-user + - api.auth.public-knowledge-profile evidence: required: - playwright_trace @@ -69,7 +71,7 @@ evidence: optional: - mailpit_message notes: - - Show identity and account metadata plus team/project memberships; current architecture should read through public admin/API facades. + - Public activity is based only on explicit public attribution; team membership never implies authorship. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/user/auth/forgot-reset-password.guarantee.yaml b/guarantees/user/auth/forgot-reset-password.guarantee.yaml deleted file mode 100644 index 5c77131f..00000000 --- a/guarantees/user/auth/forgot-reset-password.guarantee.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.user.auth.forgot-reset-password.003 -journeyIndex: 3 -type: user -subtype: auth -journey: Forgot / Reset Password -ownerPackage: "@treeseed/admin" -summary: Request and complete password reset through the auth provider; missing pieces should be handled as auth - integration work instead of custom user-table mutation. -status: active -dependencies: - journeys: - - 1 - guarantees: - - guarantee.user.auth.register-user.001 -actors: - allowed: - - anonymous_user - forbidden: - - already_authenticated_user -devices: - required: - - desktop_chromium - - mobile_chromium - optional: - - mobile_webkit -gates: - - core - - release -preconditions: - fixtures: [] - notes: - - "Journey dependencies must be satisfied: 1" -scene: - required: true - manifest: ./scenes/forgot-reset-password.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /auth/forgot-password - componentContract: auth-form guarantee harness - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - api.auth.password-reset.request.mailpit -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] -negativeCases: - - id: anonymous-denied - actor: anonymous_user - verifierRefs: - - api.auth.me.requires-user -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - optional: - - mailpit_message -notes: - - Request and complete password reset through the auth provider; missing pieces should be handled as auth integration - work instead of custom user-table mutation. -surface: admin-ui -run: - timeoutSeconds: 300 - requiredForRelease: true diff --git a/guarantees/user/auth/register-user.guarantee.yaml b/guarantees/user/auth/register-user.guarantee.yaml deleted file mode 100644 index 4bc30374..00000000 --- a/guarantees/user/auth/register-user.guarantee.yaml +++ /dev/null @@ -1,74 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.user.auth.register-user.001 -journeyIndex: 1 -type: user -subtype: auth -journey: Register User -ownerPackage: "@treeseed/admin" -summary: Create an account record and start email verification through the auth provider used by the admin/core runtime; - this is product plumbing rather than a Treeseed content operation. -status: active -dependencies: - journeys: [] - guarantees: [] -actors: - allowed: - - anonymous_user - forbidden: - - already_authenticated_user -devices: - required: - - desktop_chromium - - mobile_chromium - optional: - - mobile_webkit -gates: - - core - - release -preconditions: - fixtures: [] - notes: [] -scene: - required: true - manifest: ./scenes/register-user.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /auth/register - componentContract: auth-form guarantee harness - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - api.auth.signup.mailpit -content: - required: false - verifierRefs: [] -audit: - required: false - verifierRefs: [] -negativeCases: - - id: anonymous-denied - actor: anonymous_user - verifierRefs: - - api.auth.me.requires-user -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - optional: - - mailpit_message -notes: - - Create an account record and start email verification through the auth provider used by the admin/core runtime; this - is product plumbing rather than a Treeseed content operation. -surface: admin-ui -run: - timeoutSeconds: 300 - requiredForRelease: true diff --git a/guarantees/user/auth/scenes/forgot-reset-password.scene.yaml b/guarantees/user/auth/scenes/forgot-reset-password.scene.yaml deleted file mode 100644 index 550f9a97..00000000 --- a/guarantees/user/auth/scenes/forgot-reset-password.scene.yaml +++ /dev/null @@ -1,151 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: user.auth.forgot-reset-password.003 -title: Forgot / Reset Password -description: Acceptance scene for guarantee.user.auth.forgot-reset-password.003. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - anonymous user can open password reset - - reset form accepts account email - - reset submission reaches the check-email flow - minimumSteps: 3 - requiresInteractiveAction: true -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - - id: mobile_webkit - title: Mobile WebKit - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-password-reset - title: Open Forgot / Reset Password - action: - goto: /auth/forgot-password - expect: - urlIncludes: /auth/forgot-password - text: Reset password - - id: enter-reset-email - title: Enter reset email - action: - fill: - role: textbox - name: Email - value: owner+{{runSlug}}@treeseed.local - expect: - visible: - - role: textbox - name: Email - - id: submit-reset-request - title: Submit reset request - action: - click: - role: button - name: Send reset link - expect: - text: Check your email -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/user/auth/scenes/register-user.scene.yaml b/guarantees/user/auth/scenes/register-user.scene.yaml deleted file mode 100644 index e52a5a1b..00000000 --- a/guarantees/user/auth/scenes/register-user.scene.yaml +++ /dev/null @@ -1,207 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: user.auth.register-user.001 -title: Register User -description: Acceptance scene for guarantee.user.auth.register-user.001. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - anonymous user can open registration - - registration form accepts required profile fields - - registration submits into the email verification flow - minimumSteps: 8 - requiresInteractiveAction: true - producesState: - - key: auth.owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - - id: mobile_webkit - title: Mobile WebKit - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-registration - title: Open Register User - action: - goto: /auth/register - expect: - urlIncludes: /auth/register - text: Create account - - id: enter-first-name - title: Enter first name - action: - fill: - role: textbox - name: First name - value: Tree - expect: - visible: - - role: textbox - name: First name - - id: enter-last-name - title: Enter last name - action: - fill: - role: textbox - name: Last name - value: Seed - expect: - visible: - - role: textbox - name: Last name - - id: enter-username - title: Enter username - action: - fill: - role: textbox - name: Username - value: review-{{runShort}} - expect: - text: Username is available. - - id: enter-email - title: Enter email - action: - fill: - role: textbox - name: Email - # Staging intentionally verifies the real SMTP delivery path. Use an - # authorized mailbox and a run-specific plus address so every run is - # independently traceable without reusing a prior registration. - value: adrian.webb+review-{{runShort}}@knowledge.coop - expect: - visible: - - role: textbox - name: Email - - id: enter-password - title: Enter password - action: - fill: - css: "#registerPassword" - internal: true - value: TreeSeedReviewPass123! - expect: - text: Password - - id: confirm-password - title: Confirm password - action: - fill: - css: "[data-confirm-password-input]" - internal: true - value: TreeSeedReviewPass123! - expect: - text: Confirm password - - id: submit-registration - title: Submit registration - action: - click: - role: button - name: Create account - expect: - urlIncludes: /auth/check-email - text: Check your email -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/user/auth/scenes/user-login.scene.yaml b/guarantees/user/auth/scenes/user-login.scene.yaml index 5d204c3a..67c93d6c 100644 --- a/guarantees/user/auth/scenes/user-login.scene.yaml +++ b/guarantees/user/auth/scenes/user-login.scene.yaml @@ -9,22 +9,20 @@ journey: kind: service proves: - anonymous user can open sign-in - - sign-in form accepts credentials - - sign-in submission reaches authenticated app shell or returns a visible auth error - minimumSteps: 4 + - sign-in continues to the OAuth sign-in boundary without collecting credentials + - credentials are entered once and approval reaches the authenticated app shell or returns a visible auth error + minimumSteps: 7 requiresInteractiveAction: true - consumesState: - - key: auth.verified-owner - kind: user + consumesState: [] producesState: - - key: auth.session - kind: user + - key: auth.primary-session + kind: browser-storage mode: test: true demo: true training: true target: - app: market + app: admin environment: local baseUrl: auto browser: chromium @@ -64,6 +62,21 @@ devices: deviceScaleFactor: 2 isMobile: true hasTouch: true + - id: tablet_chromium + title: Tablet Chromium + orientation: portrait + viewport: + width: 820 + height: 1180 + video: + width: 820 + height: 1180 + output: + width: 820 + height: 1180 + deviceScaleFactor: 2 + isMobile: true + hasTouch: true - id: mobile_webkit title: Mobile WebKit orientation: portrait @@ -83,10 +96,6 @@ setup: dev: required: true reuseExisting: true - auth: - role: owner - required: true - seedOnly: true artifacts: trace: true video: true @@ -97,38 +106,72 @@ artifacts: appLogs: true workflow: - id: open-sign-in - title: Open User Login + title: Redirect to the configured Identity authority action: goto: /auth/sign-in expect: - urlIncludes: /auth/sign-in - text: Sign in + urlIncludes: /protocol/openid-connect/auth + visible: + - css: "input[name='username']" + internal: true - id: enter-identifier - title: Enter email or username + title: Enter the disposable identity at Keycloak, not Admin action: fill: - role: textbox - name: Email or username - value: visual.owner@treeseed.io + css: "input[name='username']" + internal: true + value: guarantee-{{runId}}-{{deviceId}}@treeseed.local expect: visible: - - role: textbox - name: Email or username - - id: enter-password - title: Enter password + - css: "input[name='password']" + internal: true + - id: enter-invalid-password + title: Enter an invalid password at the identity authority action: fill: - css: input[name='password'] + css: "input[name='password']" internal: true - value: TreeSeedVisualAudit!2026 + value: incorrect-password expect: - text: Password - - id: submit-sign-in - title: Submit sign in + visible: + - css: "input[name='login']" + internal: true + - id: reject-invalid-credentials + title: Reject invalid credentials without creating an application session action: click: - role: button - name: Sign in + css: "input[name='login']" + internal: true + expect: + urlIncludes: /login-actions/authenticate + visible: + - css: "input[name='password']" + internal: true + - id: enter-fixture-password + title: Enter the disposable fixture password at the identity authority + action: + fill: + css: "input[name='password']" + internal: true + value: TreeSeedGuaranteeReset123! + expect: + visible: + - css: "input[name='login']" + internal: true + - id: complete-sign-in + title: Complete PKCE callback and enter the mapped application account + action: + click: + css: "input[name='login']" + internal: true + expect: + urlIncludes: /app + visible: + - scene: app-shell + - id: reload-session + title: Reuse the opaque application session + action: + goto: /app/ expect: urlIncludes: /app visible: diff --git a/guarantees/user/auth/scenes/user-logout.scene.yaml b/guarantees/user/auth/scenes/user-logout.scene.yaml index 36c5f37e..cd53850f 100644 --- a/guarantees/user/auth/scenes/user-logout.scene.yaml +++ b/guarantees/user/auth/scenes/user-logout.scene.yaml @@ -13,12 +13,20 @@ journey: - The session-ending route produces screenshot evidence before and after logout. minimumSteps: 2 requiresInteractiveAction: true + consumesState: + - key: auth.primary-session + kind: browser-storage + - key: team.deleted + kind: marker + producesState: + - key: auth.logged-out + kind: marker mode: test: true demo: true training: true target: - app: market + app: admin environment: local baseUrl: auto browser: chromium @@ -90,21 +98,23 @@ artifacts: appLogs: true workflow: - id: open-account-sessions - title: Open logout confirmation + title: Open the authenticated application shell action: - goto: /auth/logout + goto: /app/ expect: - urlIncludes: /auth/logout - text: Sign out + urlIncludes: /app + visible: + - scene: start.orientation - id: submit-user-logout title: End the current session action: click: role: button name: Sign out + revealWith: { role: button, name: Open team operations } expect: - urlIncludes: /auth/sign-in - text: Sign in + urlIncludes: / + text: TreeSeed chapters: [] overlays: [] diagrams: [] diff --git a/guarantees/user/auth/scenes/verify-email.scene.yaml b/guarantees/user/auth/scenes/verify-email.scene.yaml deleted file mode 100644 index d621ebbe..00000000 --- a/guarantees/user/auth/scenes/verify-email.scene.yaml +++ /dev/null @@ -1,154 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: user.auth.verify-email.002 -title: Verify Email -description: Acceptance scene for guarantee.user.auth.verify-email.002. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - newly registered user can open the email-check state - - the email-check state directs a user back to sign in after verification - - confirmation delivery and token exchange remain API-owned evidence - minimumSteps: 3 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - producesState: - - key: auth.verified-owner - kind: user -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop_chromium - profiles: - - id: desktop_chromium - title: Desktop Chromium - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - - id: mobile_chromium - title: Mobile Chromium - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - - id: mobile_webkit - title: Mobile WebKit - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 390 - height: 844 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true -setup: - dev: - required: true - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-check-email - title: Open email verification holding page - action: - goto: /auth/check-email?kind=verify - expect: - urlIncludes: /auth/check-email - text: Check your email - - id: continue-after-verification - title: Continue after verifying email - action: - click: - role: link - name: I verified my email - expect: - urlIncludes: /auth/sign-in - text: Sign in - - id: inspect-sign-in-handoff - title: Inspect sign-in handoff after confirmation - action: - goto: /auth/sign-in?returnTo=%2Fapp%2F - expect: - urlIncludes: /auth/sign-in - text: Sign in -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: {} -visualAudit: - enabled: false diff --git a/guarantees/user/auth/user-login.guarantee.yaml b/guarantees/user/auth/user-login.guarantee.yaml index 61f7f7ca..e93407a6 100644 --- a/guarantees/user/auth/user-login.guarantee.yaml +++ b/guarantees/user/auth/user-login.guarantee.yaml @@ -9,10 +9,8 @@ summary: Establish an authenticated session for Market/admin surfaces; downstrea authenticated user context. status: active dependencies: - journeys: - - 2 - guarantees: - - guarantee.user.auth.verify-email.002 + journeys: [] + guarantees: [] actors: allowed: - anonymous_user @@ -21,6 +19,7 @@ actors: devices: required: - desktop_chromium + - tablet_chromium - mobile_chromium optional: - mobile_webkit @@ -30,16 +29,17 @@ gates: preconditions: fixtures: [] notes: - - "Journey dependencies must be satisfied: 2" + - Deployment provisions a disposable Identity account and an explicit API principal mapping before the scene. scene: required: true manifest: ./scenes/user-login.scene.yaml + executionKey: admin.identity.login mode: acceptance: true demo: true training: true entryRoute: /auth/sign-in - componentContract: auth-form guarantee harness + componentContract: Identity OIDC redirect and opaque application-session boundary expectedEvidence: - playwright_trace - scene_video diff --git a/guarantees/user/auth/user-logout.guarantee.yaml b/guarantees/user/auth/user-logout.guarantee.yaml index fdaef724..4799dce5 100644 --- a/guarantees/user/auth/user-logout.guarantee.yaml +++ b/guarantees/user/auth/user-logout.guarantee.yaml @@ -5,13 +5,16 @@ type: user subtype: auth journey: User Logout ownerPackage: "@treeseed/admin" -summary: End the provider session and clear local admin state before redirecting to the anonymous sign-in surface. +summary: Revoke this application session and clear its host-only cookies without ending another application's identity session. status: active dependencies: - journeys: - - 4 + journeys: [] guarantees: - - guarantee.user.auth.user-login.004 + - guarantee.user.account.view-user-profile.010 + - guarantee.user.account.manage-sessions.007 + - guarantee.user.account.manage-notifications.008 + - guarantee.user.account.manage-appearance.009 + - guarantee.team.team.delete-team.016 actors: allowed: - verified_user @@ -35,11 +38,12 @@ preconditions: scene: required: true manifest: ./scenes/user-logout.scene.yaml + executionKey: admin.identity.logout mode: acceptance: true demo: true training: true - entryRoute: /auth/logout + entryRoute: /app/ componentContract: redirect/session guarantee harness expectedEvidence: - playwright_trace @@ -55,8 +59,8 @@ content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.auth.lifecycle.audit] negativeCases: - id: anonymous-denied actor: anonymous_user @@ -70,7 +74,7 @@ evidence: optional: - mailpit_message notes: - - Uses the canonical /auth/logout route to revoke the API session, clear web cookies, and return to /auth/sign-in?signedOut=1. + - POST /auth/logout requires CSRF and matching Origin, revokes the opaque application handle, and returns to the public application root. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/user/auth/verify-email.guarantee.yaml b/guarantees/user/auth/verify-email.guarantee.yaml index a5850533..9eb6144b 100644 --- a/guarantees/user/auth/verify-email.guarantee.yaml +++ b/guarantees/user/auth/verify-email.guarantee.yaml @@ -5,22 +5,22 @@ type: user subtype: auth journey: Verify Email ownerPackage: "@treeseed/admin" -summary: Complete auth-provider verification then redirect into the authenticated Market/admin shell; implementation - should not bypass the provider session model. +summary: Verify an additional application contact email without changing the sign-in identity or linking accounts. status: active dependencies: journeys: - - 1 + - 4 guarantees: - - guarantee.user.auth.register-user.001 + - guarantee.user.auth.user-login.004 actors: allowed: - - anonymous_user + - verified_user forbidden: - - already_authenticated_user + - anonymous_user devices: required: - desktop_chromium + - tablet_chromium - mobile_chromium optional: - mobile_webkit @@ -30,15 +30,16 @@ gates: preconditions: fixtures: [] notes: - - "Journey dependencies must be satisfied: 1" + - A mapped sign-in identity already exists; matching contact emails never link identities. scene: required: true - manifest: ./scenes/verify-email.scene.yaml + manifest: ../account/scenes/edit-account-settings.scene.yaml + executionKey: admin.account.edit-profile mode: acceptance: true demo: true training: true - entryRoute: /auth/confirm-email + entryRoute: /app/account componentContract: redirect/session guarantee harness expectedEvidence: - playwright_trace @@ -49,13 +50,13 @@ scene: api: required: true verifierRefs: - - api.auth.signup.mailpit + - api.auth.email.lifecycle content: required: false verifierRefs: [] audit: - required: false - verifierRefs: [] + required: true + verifierRefs: [api.auth.lifecycle.audit] negativeCases: - id: anonymous-denied actor: anonymous_user @@ -69,9 +70,8 @@ evidence: optional: - mailpit_message notes: - - Complete auth-provider verification then redirect into the authenticated Market/admin shell; implementation should - not bypass the provider session model. - - The scene proves the hosted check-email and sign-in handoff; API acceptance owns confirmation delivery and token behavior. + - The shared account scene adds a contact email, consumes its delivered confirmation once, and verifies the resulting record. + - Identity owns registration, sign-in email verification, and password recovery. Admin does not issue login credentials. surface: admin-ui run: timeoutSeconds: 300 diff --git a/guarantees/verifiers/ui.verifiers.yaml b/guarantees/verifiers/ui.verifiers.yaml index 2b054be2..554811a9 100644 --- a/guarantees/verifiers/ui.verifiers.yaml +++ b/guarantees/verifiers/ui.verifiers.yaml @@ -1,16 +1,168 @@ schemaVersion: treeseed.guarantee-verifiers/v1 ownerPackage: "@treeseed/admin" verifiers: + admin.knowledge.ui-contracts: + kind: vitestCase + ownerPackage: "@treeseed/admin" + testFile: tests/contract/knowledge-management/knowledge-management-architecture.test.ts + description: The authoring, lifecycle, review, publication, reader, search, and pack UI composes canonical shared components and stable scene controls. + api.knowledge.control-plane: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/unit/knowledge + description: Exact-ref catalogs, permissions, platform ownership, atomic publication, rollback, and immutable pack execution pass. + api.knowledge.run-correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-knowledge-run-state.ts + args: [publication] + description: The exact UI-authored book and page resolve to one TreeDX workspace, independent review, Git commit, atomic manifest revision, operation, and metadata-only audits. + api.knowledge.pack.run-correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-knowledge-run-state.ts + args: [pack] + description: The exact run book and page are present in the same completed immutable single-book pack, publication revision, private artifact, and audit event. + api.knowledge.collection.run-correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-knowledge-run-state.ts + args: [collection] + description: The UI-created saved collection and completed pack contain exactly the two explicitly selected run-authorized books. + api.knowledge.lifecycle.run-correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-knowledge-run-state.ts + args: [lifecycle] + description: The exact UI-created page and book each archive and restore through distinct independently reviewed Git, TreeDX, manifest, and audit correlations. + api.knowledge.contextual-policy: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/contract/api/contextual-knowledge-api.test.ts + description: Federated contextual lookup and TreeDX search authorize before returning knowledge or relationships. + sdk.knowledge.safe-content: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/content/knowledge-catalog.test.ts + description: AST validation accepts fenced source examples and rejects executable MDX, raw HTML, unsafe links, and unsupported JSX. + sdk.knowledge.pack-integrity: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/content/knowledge-pack-snapshot.test.ts + description: Selected-book artifacts are deterministic and preserve exact atomic publication source closure. + sdk.knowledge.content-sync: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/content/content-sync.test.ts + description: Local, upstream, TreeDX, and atomic publication refs must agree before a safe fast-forward. + core.knowledge.starlight-reader: + kind: packageScript + ownerPackage: "@treeseed/core" + cwd: packages/core + command: check + description: Canonical Starlight reader routes compile for the federated published knowledge runtime. + sdk.contextual-help.content: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/content/contextual-help.test.ts + description: Help topic schemas, relationships, safe Markdown rendering, revisioning, context resolution, and search indexing pass. + api.contextual-help.policy: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/contract/api/contextual-help-api.test.ts + description: Public and protected help topics, related relationships, search, and unavailable runtime behavior fail closed without policy leakage. + ui.contextual-help.dialog: + kind: vitestCase + ownerPackage: "@treeseed/ui" + testFile: tests/unit/foundation.test.ts + testName: keeps contextual help shell-level and search lazy + description: One shell-owned dialog and trigger transport owns lazy help loading, scoped search, and shared modal behavior. + admin.contextual-help.coverage: + kind: vitestCase + ownerPackage: "@treeseed/admin" + testFile: tests/contract/contextual-help/contextual-help-architecture.test.ts + description: Every active account, team, invitation, service, and vault route and trigger resolves to canonical Admin Markdown content. + sdk.feedback.contracts: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/feedback/feedback-contracts.test.ts + description: Feedback types, lifecycle states, privacy schemas, and platform-only permissions remain stable. + api.feedback.management: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/integration/api/feedback/feedback-management.test.ts + description: Authenticated persistence, redacted PNG validation, platform administration, metadata-only audit, and privacy-safe export contracts pass. + api.feedback.run-correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-feedback-run-state.ts + args: [verify] + description: The exact UI-created reports, private capture, status history, metadata-only audits, and runner-generated export resolve to the same run records. + api.feedback.run-cleanup: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-feedback-run-state.ts + args: [cleanup] + description: Run-owned feedback, attachments, exports, runner records, and correlated audit fixtures are removed from local acceptance storage. + ui.feedback.system: + kind: vitestCase + ownerPackage: "@treeseed/ui" + testFile: tests/unit/foundation.test.ts + testName: keeps feedback non-modal, responsive, private, and shell-owned + description: The shared shell-owned feedback panel is non-modal, responsive, idempotent, and free from private client persistence. + admin.feedback.ui-contracts: + kind: vitestCase + ownerPackage: "@treeseed/admin" + testFile: tests/contract/feedback-management/feedback-management-architecture.test.ts + description: Authenticated launcher, platform-only routes, shared UI composition, help, triage, and private attachment views remain canonical. + sdk.service.vault.crypto: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/secrets-capability/service-vault-crypto.test.ts + description: Argon2id, XChaCha20-Poly1305, X25519 grants, contextual binding, passphrase rotation, and provider schemas pass real cryptographic tests. + sdk.scene.secret-evidence-redaction: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/scenes/evidence/scenes-evidence.test.ts + description: Persisted normalized scenes and Playwright trace archives retain useful evidence while replacing passphrases, credentials, tokens, and private keys. + api.service.management.contracts: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/integration/api/teams/services/service-management.test.ts + description: Provider metadata, ciphertext persistence, plaintext rejection, grants, audit correlation, and operation-lease replay protection pass through the real API. + api.service.management.run-cleanup: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/cleanup-service-run-state.ts + description: The exact UI-disconnected run services retain no connection-owned records, after which local fixture-only team vault state is removed. + admin.service.ui-contracts: + kind: vitestCase + ownerPackage: "@treeseed/admin" + testFile: tests/contract/service-management/service-management-architecture.test.ts + description: Service routes use the shared UI/form system, active-team scoping, timezone timestamps, and client-only cryptographic adapters. + api.auth.lifecycle.audit: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/integration/api/treedx/repositories/seeds-and-treedx.test.ts + testName: owns web auth lifecycle and acceptance session seeding in the API + description: Web identity lifecycle records canonical dotted audit events and durable session evidence. api.auth.signup.mailpit: kind: apiAcceptanceCase caseId: auth.web.sign-up.sends-confirmation-email ownerPackage: "@treeseed/api" - description: Signup succeeds and emits a verification email into local Mailpit. + description: Signup emits a verification email whose confirmation link uses the configured web origin. api.auth.password-reset.request.mailpit: kind: apiAcceptanceCase caseId: auth.password-reset.request.mailpit ownerPackage: "@treeseed/api" - description: Password reset request succeeds and emits a reset email into local Mailpit. + description: Password reset emits an email whose reset link uses the configured web origin. api.auth.signin: kind: apiAcceptanceCase caseId: auth.web.sign-in.site-admin @@ -31,6 +183,23 @@ verifiers: caseId: auth.profile.update.team-owner ownerPackage: "@treeseed/api" description: Authenticated users can update profile details. + api.auth.public-knowledge-profile: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/integration/api/profiles/public-knowledge-profiles.test.ts + testName: publishes explicit knowledge while redacting memberships and private work + description: Public user and team profiles expose only explicitly public knowledge and attribution without leaking memberships or private work. + api.auth.account-preferences: + kind: apiAcceptanceCase + caseId: auth.account-preferences.team-owner + ownerPackage: "@treeseed/api" + description: Authenticated users can persist the IANA time zone used for UI timestamps and notification scheduling. + api.auth.email.lifecycle: + kind: vitestCase + ownerPackage: "@treeseed/api" + testFile: tests/integration/api/accounts/authentication-and-identity.test.ts + testName: supports multiple verified account emails for login, primary selection, deletion, reset, and invite lookup + description: A signed-in account can add a pending email, consume its one-time confirmation token, observe verified persistence, and then use the address for authentication. api.auth.sessions: kind: apiAcceptanceCase caseId: auth.sessions.team-owner @@ -41,1588 +210,157 @@ verifiers: caseId: auth.appearance.team-owner ownerPackage: "@treeseed/api" description: Authenticated users can update appearance preference. + api.auth.notifications: + kind: apiAcceptanceCase + caseId: auth.notifications.team-owner + ownerPackage: "@treeseed/api" + description: Authenticated users can replace global and authorized-project notification preferences without data leakage. api.auth.account.blockers: kind: apiAcceptanceCase caseId: auth.account-blockers.team-viewer ownerPackage: "@treeseed/api" description: Authenticated users can inspect account deletion blockers. - api.team.list.owner: - kind: apiAcceptanceCase - caseId: teams.list.team-owner - ownerPackage: "@treeseed/api" - description: Team owner can list teams. - api.team.list.nonmember: - kind: apiAcceptanceCase - caseId: teams.list.non-member - ownerPackage: "@treeseed/api" - description: Non-member team listing remains bounded to authorized teams. - api.team.create: - kind: apiAcceptanceCase - caseId: teams.create.team-owner - ownerPackage: "@treeseed/api" - description: Authenticated user can create a team. - api.team.update: - kind: apiAcceptanceCase - caseId: teams.update.team-owner - ownerPackage: "@treeseed/api" - description: Team owner can update team settings. - api.team.invite.mailpit: - kind: apiAcceptanceCase - caseId: teams.invite.team-owner - ownerPackage: "@treeseed/api" - description: Team owner can invite a member and Mailpit receives the invite email. - api.team.members.owner: - kind: apiAcceptanceCase - caseId: team-role-matrix.team-members.teamOwner - ownerPackage: "@treeseed/api" - description: Team owner can inspect team members. - api.team.members.nonmember: - kind: apiAcceptanceCase - caseId: team-role-matrix.team-members.nonMember - ownerPackage: "@treeseed/api" - description: Non-members cannot inspect team membership. - api.team.permissions.owner: - kind: apiAcceptanceCase - caseId: team-role-matrix.team-permissions.teamOwner - ownerPackage: "@treeseed/api" - description: Team owner can inspect team permissions. - api.team.member.role: - kind: apiAcceptanceCase - caseId: teams.member-role.team-owner - ownerPackage: "@treeseed/api" - description: Team owner can change a member role. - api.team.member.remove: - kind: apiAcceptanceCase - caseId: teams.member-remove.team-owner - ownerPackage: "@treeseed/api" - description: Team owner can remove a member. - api.team.deletion-blockers: - kind: apiAcceptanceCase - caseId: teams.deletion-blockers.team-owner - ownerPackage: "@treeseed/api" - description: Team owner can inspect team deletion blockers. - api.team.profile: - kind: apiAcceptanceCase - caseId: teams.profile.by-name - ownerPackage: "@treeseed/api" - description: Public team profile can be loaded by name. - admin.agent.monitor.runtime-ui: - kind: scene + api.team.create.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [create] + description: The UI-created run team exists with owner membership and its correlated team.created event. + api.team.active.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [active] + description: The exact UI-selected run team remains active and accessible. + api.team.update.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [update] + description: The UI-updated run team identity and team.updated event refer to the same record. + api.team.overview.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [overview] + description: Operational overview state resolves for the exact UI-created run team. + api.team.public-profile.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [public-profile] + description: The exact run-created team profile exposes its public knowledge projection without private membership or operational fields. + api.team.invite.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [invite] + description: The exact UI invitation remains pending and correlated create/resend/revoke audit events exist. + api.team.accept.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [accept] + description: The invited recipient became a member only after explicit UI acceptance. + api.team.role.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [role] + description: The exact UI-created membership has its selected role and correlated audit event. + api.team.remove.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [remove] + description: The exact UI-created membership is absent and its correlated removal event exists. + api.team.delete.correlated: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [delete] + description: The UI-deleted run team and owned records are absent while a non-sensitive deletion tombstone remains. + admin.team.production-readiness: + kind: nodeScript + ownerPackage: "@treeseed/api" + cwd: packages/api + command: scripts/guarantees/verify-team-run-state.ts + args: [cleanup] + description: Every run-owned team is gone after the complete UI lifecycle. + admin.team.ui-contracts: + kind: vitestCase ownerPackage: "@treeseed/admin" - description: Admin runtime UI scene verifies project agent and capacity runtime monitoring surfaces. - admin.agent.monitor.unauthorized-denied: - kind: scene - ownerPackage: "@treeseed/admin" - description: Admin monitoring scene verifies unauthorized users are denied or redirected. - admin.capacity.capacity.approve-capacity.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/approve-capacity api verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.approve-capacity.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/approve-capacity audit verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.approve-capacity.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/approve-capacity content verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.approve-capacity.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.inspect-provider-check-ins - description: "@treeseed/admin capacity/capacity/approve-capacity negative verifier backed by API acceptance case capacity.provider.inspect-provider-check-ins." - admin.capacity.capacity.deploy-capacity.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/deploy-capacity api verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.deploy-capacity.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/deploy-capacity audit verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.deploy-capacity.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/deploy-capacity content verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.deploy-capacity.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.inspect-provider-check-ins - description: "@treeseed/admin capacity/capacity/deploy-capacity negative verifier backed by API acceptance case capacity.provider.inspect-provider-check-ins." - admin.capacity.capacity.monitor-capacity.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/monitor-capacity api verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.monitor-capacity.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/monitor-capacity audit verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.monitor-capacity.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/monitor-capacity content verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.monitor-capacity.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.inspect-provider-check-ins - description: "@treeseed/admin capacity/capacity/monitor-capacity negative verifier backed by API acceptance case capacity.provider.inspect-provider-check-ins." - admin.capacity.capacity.revoke-capacity.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/revoke-capacity api verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.revoke-capacity.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/revoke-capacity audit verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.revoke-capacity.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/revoke-capacity content verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.revoke-capacity.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.inspect-provider-check-ins - description: "@treeseed/admin capacity/capacity/revoke-capacity negative verifier backed by API acceptance case capacity.provider.inspect-provider-check-ins." - admin.capacity.capacity.shut-down-capacity.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/shut-down-capacity api verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.shut-down-capacity.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/shut-down-capacity audit verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.shut-down-capacity.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.usage.review-capacity-usage - description: "@treeseed/admin capacity/capacity/shut-down-capacity content verifier backed by API acceptance case capacity.usage.review-capacity-usage." - admin.capacity.capacity.shut-down-capacity.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.inspect-provider-check-ins - description: "@treeseed/admin capacity/capacity/shut-down-capacity negative verifier backed by API acceptance case capacity.provider.inspect-provider-check-ins." - admin.capacity.registration.rotate-capacity-key.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.register-capacity-provider - description: "@treeseed/admin capacity/registration/rotate-capacity-key api verifier backed by API acceptance case capacity.provider.register-capacity-provider." - admin.capacity.registration.rotate-capacity-key.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.register-capacity-provider - description: "@treeseed/admin capacity/registration/rotate-capacity-key audit verifier backed by API acceptance case capacity.provider.register-capacity-provider." - admin.capacity.registration.rotate-capacity-key.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.register-capacity-provider - description: "@treeseed/admin capacity/registration/rotate-capacity-key content verifier backed by API acceptance case capacity.provider.register-capacity-provider." - admin.capacity.registration.rotate-capacity-key.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: capacity.provider.inspect-provider-check-ins - description: "@treeseed/admin capacity/registration/rotate-capacity-key negative verifier backed by API acceptance case capacity.provider.inspect-provider-check-ins." - admin.host.host.create-host.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/create-host api verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.create-host.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/create-host audit verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.create-host.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/create-host content verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.create-host.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: platform.operations.team-viewer-denied - description: "@treeseed/admin host/host/create-host negative verifier backed by API acceptance case platform.operations.team-viewer-denied." - admin.host.host.delete-host.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/delete-host api verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.delete-host.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/delete-host audit verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.delete-host.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/delete-host content verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.delete-host.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: platform.operations.team-viewer-denied - description: "@treeseed/admin host/host/delete-host negative verifier backed by API acceptance case platform.operations.team-viewer-denied." - admin.host.host.edit-host.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/edit-host api verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.edit-host.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/edit-host audit verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.edit-host.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/host/edit-host content verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.host.edit-host.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: platform.operations.team-viewer-denied - description: "@treeseed/admin host/host/edit-host negative verifier backed by API acceptance case platform.operations.team-viewer-denied." - admin.host.secrets.create-passphrase.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/secrets/create-passphrase api verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.secrets.create-passphrase.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/secrets/create-passphrase audit verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.secrets.create-passphrase.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/secrets/create-passphrase content verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.secrets.create-passphrase.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: platform.operations.team-viewer-denied - description: "@treeseed/admin host/secrets/create-passphrase negative verifier backed by API acceptance case platform.operations.team-viewer-denied." - admin.host.secrets.reset-passphrase.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/secrets/reset-passphrase api verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.secrets.reset-passphrase.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/secrets/reset-passphrase audit verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.secrets.reset-passphrase.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: host.reconciliation.preview-host-plan - description: "@treeseed/admin host/secrets/reset-passphrase content verifier backed by API acceptance case host.reconciliation.preview-host-plan." - admin.host.secrets.reset-passphrase.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: platform.operations.team-viewer-denied - description: "@treeseed/admin host/secrets/reset-passphrase negative verifier backed by API acceptance case platform.operations.team-viewer-denied." - admin.marketplace-seller.fulfillment.record-fulfillment.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous - description: "@treeseed/admin marketplace-seller/fulfillment/record-fulfillment api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous." - admin.marketplace-seller.fulfillment.record-fulfillment.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous - description: "@treeseed/admin marketplace-seller/fulfillment/record-fulfillment audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous." - admin.marketplace-seller.fulfillment.record-fulfillment.content: - kind: apiAcceptanceCase + testFile: tests/contract/team-management/team-management-architecture.test.ts + description: Admin route, interaction ownership, progressive-enhancement, failure-state, consent, and lifecycle contracts are complete. + api.team.lifecycle-contracts: + kind: vitestCase ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous - description: "@treeseed/admin marketplace-seller/fulfillment/record-fulfillment content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous." - admin.marketplace-seller.fulfillment.record-fulfillment.negative: + testFile: tests/integration/api/teams/lifecycle + description: Invitation consent, lifecycle, blocker, cleanup, and transactional last-owner contracts pass. + sdk.team.ui-evidence-trust: + kind: vitestCase + ownerPackage: "@treeseed/sdk" + testFile: tests/unit/guarantees/trust/ui-evidence-trust.test.ts + description: Exact device, per-node status, source closure, release fail-closed, and UI feature-contract evidence rules pass. + api.team.create.anonymous-denied: kind: apiAcceptanceCase + caseId: teams.create.anonymous-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/fulfillment/record-fulfillment negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.listings.approve-listing.api: + api.team.update.contributor-denied: kind: apiAcceptanceCase + caseId: teams.update.contributor-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/approve-listing api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.approve-listing.audit: + api.team.overview.anonymous-denied: kind: apiAcceptanceCase + caseId: teams.overview.anonymous-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/approve-listing audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.approve-listing.content: + api.team.overview.nonmember-denied: kind: apiAcceptanceCase + caseId: teams.overview.nonmember-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/approve-listing content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.approve-listing.negative: + api.team.invite.contributor-denied: kind: apiAcceptanceCase + caseId: teams.invite.contributor-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/listings/approve-listing negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.listings.create-product-listing.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/create-product-listing api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.create-product-listing.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/create-product-listing audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.create-product-listing.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/create-product-listing content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.create-product-listing.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/listings/create-product-listing negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.listings.manage-listing.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/manage-listing api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.manage-listing.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/manage-listing audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.manage-listing.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/manage-listing content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.manage-listing.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/listings/manage-listing negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.listings.submit-listing-for-review.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/submit-listing-for-review api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.submit-listing-for-review.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/submit-listing-for-review audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.submit-listing-for-review.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/listings/submit-listing-for-review content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.listings.submit-listing-for-review.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/listings/submit-listing-for-review negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.onboarding.approve-seller.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/onboarding/approve-seller api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.onboarding.approve-seller.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/onboarding/approve-seller audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.onboarding.approve-seller.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/onboarding/approve-seller content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.onboarding.approve-seller.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/onboarding/approve-seller negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.onboarding.request-seller-setup.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/onboarding/request-seller-setup api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.onboarding.request-seller-setup.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/onboarding/request-seller-setup audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.onboarding.request-seller-setup.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/onboarding/request-seller-setup content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.onboarding.request-seller-setup.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/onboarding/request-seller-setup negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.refunds.issue-refund.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous - description: "@treeseed/admin marketplace-seller/refunds/issue-refund api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous." - admin.marketplace-seller.refunds.issue-refund.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous - description: "@treeseed/admin marketplace-seller/refunds/issue-refund audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous." - admin.marketplace-seller.refunds.issue-refund.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous - description: "@treeseed/admin marketplace-seller/refunds/issue-refund content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.anonymous." - admin.marketplace-seller.refunds.issue-refund.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/refunds/issue-refund negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.marketplace-seller.sales.view-seller-sales.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/sales/view-seller-sales api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.sales.view-seller-sales.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/sales/view-seller-sales audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.sales.view-seller-sales.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward - description: "@treeseed/admin marketplace-seller/sales/view-seller-sales content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.marketSteward." - admin.marketplace-seller.sales.view-seller-sales.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember - description: "@treeseed/admin marketplace-seller/sales/view-seller-sales negative verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.commerce.marketplace.nonMember." - admin.project.agent.create-agent.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/create-agent api verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.create-agent.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/create-agent audit verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.create-agent.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/create-agent content verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.create-agent.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/agent/create-agent negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.agent.delete-agent.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/delete-agent api verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.delete-agent.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/delete-agent audit verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.delete-agent.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/delete-agent content verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.delete-agent.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/agent/delete-agent negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.agent.edit-agent.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/edit-agent api verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.edit-agent.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/edit-agent audit verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.edit-agent.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.compile-decision-assignment-graph - description: "@treeseed/admin project/agent/edit-agent content verifier backed by API acceptance case agent.graph.compile-decision-assignment-graph." - admin.project.agent.edit-agent.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/agent/edit-agent negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.allocation.allocate-agent-capacity.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.reserve-planning-capacity - description: "@treeseed/admin project/allocation/allocate-agent-capacity api verifier backed by API acceptance case agent.graph.reserve-planning-capacity." - admin.project.allocation.allocate-agent-capacity.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.reserve-planning-capacity - description: "@treeseed/admin project/allocation/allocate-agent-capacity audit verifier backed by API acceptance case agent.graph.reserve-planning-capacity." - admin.project.allocation.allocate-agent-capacity.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.reserve-planning-capacity - description: "@treeseed/admin project/allocation/allocate-agent-capacity content verifier backed by API acceptance case agent.graph.reserve-planning-capacity." - admin.project.allocation.allocate-agent-capacity.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/allocation/allocate-agent-capacity negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.allocation.allocate-project-capacity.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.reserve-planning-capacity - description: "@treeseed/admin project/allocation/allocate-project-capacity api verifier backed by API acceptance case agent.graph.reserve-planning-capacity." - admin.project.allocation.allocate-project-capacity.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.reserve-planning-capacity - description: "@treeseed/admin project/allocation/allocate-project-capacity audit verifier backed by API acceptance case agent.graph.reserve-planning-capacity." - admin.project.allocation.allocate-project-capacity.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: agent.graph.reserve-planning-capacity - description: "@treeseed/admin project/allocation/allocate-project-capacity content verifier backed by API acceptance case agent.graph.reserve-planning-capacity." - admin.project.allocation.allocate-project-capacity.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/allocation/allocate-project-capacity negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.book.create-book.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/create-book api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.create-book.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/create-book audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.create-book.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/create-book content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.create-book.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/book/create-book negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.book.delete-book.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/delete-book api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.delete-book.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/delete-book audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.delete-book.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/delete-book content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.delete-book.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/book/delete-book negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.book.download-book.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/download-book api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.download-book.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/download-book audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.download-book.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/download-book content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.download-book.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/book/download-book negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.book.edit-book.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/edit-book api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.edit-book.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/edit-book audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.edit-book.content: - kind: apiAcceptanceCase + api.team.invitation.mismatch-denied: + kind: vitestCase ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/edit-book content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.edit-book.negative: - kind: apiAcceptanceCase + testFile: tests/integration/api/teams/lifecycle/invitation-consent.test.ts + testName: rejects invitation acceptance by a verified mismatched user + api.team.invitation.terminal-states: + kind: vitestCase ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/book/edit-book negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.book.search-books.api: + testFile: tests/integration/api/teams/lifecycle/invitation-consent.test.ts + testName: preserves explicit expired revoked accepted and replay states + api.team.role.contributor-denied: kind: apiAcceptanceCase + caseId: teams.role.contributor-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/search-books api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.search-books.audit: + api.team.remove.contributor-denied: kind: apiAcceptanceCase + caseId: teams.remove.contributor-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/search-books audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.search-books.content: + api.team.lifecycle.project-lead-denied: kind: apiAcceptanceCase + caseId: teams.lifecycle.project-lead-denied ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/book/search-books content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.book.search-books.negative: - kind: apiAcceptanceCase + api.team.public-profile.archived-not-found: + kind: vitestCase ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/book/search-books negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.decision.create-note-on-decision.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/decision/create-note-on-decision api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.decision.create-note-on-decision.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/decision/create-note-on-decision audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.decision.create-note-on-decision.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/decision/create-note-on-decision content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.decision.create-note-on-decision.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/decision/create-note-on-decision negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.decision.search-decisions.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/decision/search-decisions api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.decision.search-decisions.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/decision/search-decisions audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.decision.search-decisions.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/decision/search-decisions content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.decision.search-decisions.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/decision/search-decisions negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.knowledge.create-book-page.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/create-book-page api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.create-book-page.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/create-book-page audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.create-book-page.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/create-book-page content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.create-book-page.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/knowledge/create-book-page negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.knowledge.delete-book-page.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/delete-book-page api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.delete-book-page.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/delete-book-page audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.delete-book-page.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/delete-book-page content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.delete-book-page.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/knowledge/delete-book-page negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.knowledge.edit-book-page.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/edit-book-page api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.edit-book-page.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/edit-book-page audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.edit-book-page.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/edit-book-page content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.edit-book-page.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/knowledge/edit-book-page negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.knowledge.review-backlinks.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/review-backlinks api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.review-backlinks.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/review-backlinks audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.review-backlinks.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/knowledge/review-backlinks content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.knowledge.review-backlinks.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/knowledge/review-backlinks negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.library.download-library.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/library/download-library api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.library.download-library.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/library/download-library audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.library.download-library.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/library/download-library content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.library.download-library.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/library/download-library negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.library.rebuild-library-index.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/library/rebuild-library-index api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.library.rebuild-library-index.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/library/rebuild-library-index audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.library.rebuild-library-index.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/library/rebuild-library-index content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.library.rebuild-library-index.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/library/rebuild-library-index negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.objective.create-note-on-objective.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/create-note-on-objective api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.create-note-on-objective.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/create-note-on-objective audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.create-note-on-objective.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/create-note-on-objective content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.create-note-on-objective.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/objective/create-note-on-objective negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.objective.create-objective.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/create-objective api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.create-objective.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/create-objective audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.create-objective.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/create-objective content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.create-objective.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/objective/create-objective negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.objective.delete-objective.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/delete-objective api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.delete-objective.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/delete-objective audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.delete-objective.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/delete-objective content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.delete-objective.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/objective/delete-objective negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.objective.edit-objective.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/edit-objective api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.edit-objective.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/edit-objective audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.edit-objective.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/edit-objective content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.edit-objective.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/objective/edit-objective negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.objective.search-objectives.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/search-objectives api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.search-objectives.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/search-objectives audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.search-objectives.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/objective/search-objectives content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.objective.search-objectives.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/objective/search-objectives negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.project.create-project.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/create-project api verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.create-project.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/create-project audit verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.create-project.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/create-project content verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.create-project.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/project/create-project negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.project.destroy-project.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/destroy-project api verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.destroy-project.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/destroy-project audit verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.destroy-project.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/destroy-project content verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.destroy-project.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/project/destroy-project negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.project.edit-project-settings.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/edit-project-settings api verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.edit-project-settings.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/edit-project-settings audit verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.edit-project-settings.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/edit-project-settings content verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.edit-project-settings.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/project/edit-project-settings negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.project.monitor-project.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/monitor-project api verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.monitor-project.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/monitor-project audit verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.monitor-project.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/monitor-project content verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.monitor-project.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/project/monitor-project negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.project.view-project-profile.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/view-project-profile api verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.view-project-profile.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/view-project-profile audit verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.view-project-profile.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.teamOwner - description: "@treeseed/admin project/project/view-project-profile content verifier backed by API acceptance case team-role-matrix.project-summary.teamOwner." - admin.project.project.view-project-profile.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/project/view-project-profile negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.proposal.create-note-on-proposal.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/create-note-on-proposal api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.create-note-on-proposal.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/create-note-on-proposal audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.create-note-on-proposal.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/create-note-on-proposal content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.create-note-on-proposal.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/proposal/create-note-on-proposal negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.proposal.create-proposal.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/create-proposal api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.create-proposal.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/create-proposal audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.create-proposal.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/create-proposal content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.create-proposal.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/proposal/create-proposal negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.proposal.delete-proposal.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/delete-proposal api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.delete-proposal.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/delete-proposal audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.delete-proposal.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/delete-proposal content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.delete-proposal.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/proposal/delete-proposal negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.proposal.edit-proposal.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/edit-proposal api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.edit-proposal.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/edit-proposal audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.edit-proposal.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/edit-proposal content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.edit-proposal.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/proposal/edit-proposal negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.proposal.proposal-inbox.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/proposal-inbox api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.proposal-inbox.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/proposal-inbox audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.proposal-inbox.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/proposal-inbox content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.proposal-inbox.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/proposal/proposal-inbox negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.proposal.search-proposals.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/search-proposals api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.search-proposals.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/search-proposals audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.search-proposals.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/search-proposals content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.search-proposals.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/proposal/search-proposals negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.proposal.vote-on-proposal.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/vote-on-proposal api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.vote-on-proposal.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/vote-on-proposal audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.vote-on-proposal.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/proposal/vote-on-proposal content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.proposal.vote-on-proposal.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/proposal/vote-on-proposal negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.question.answer-question.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/answer-question api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.answer-question.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/answer-question audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.answer-question.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/answer-question content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.answer-question.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/question/answer-question negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.question.ask-question.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/ask-question api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.ask-question.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/ask-question audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.ask-question.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/ask-question content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.ask-question.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/question/ask-question negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.question.delete-question.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/delete-question api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.delete-question.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/delete-question audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.delete-question.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/delete-question content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.delete-question.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/question/delete-question negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.question.edit-question.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/edit-question api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.edit-question.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/edit-question audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.edit-question.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/edit-question content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.edit-question.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/question/edit-question negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.project.question.search-questions-answers.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/search-questions-answers api verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.search-questions-answers.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/search-questions-answers audit verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.search-questions-answers.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner - description: "@treeseed/admin project/question/search-questions-answers content verifier backed by API acceptance case descriptor-executable-role-matrix.get.v1.ui.knowledge.teamOwner." - admin.project.question.search-questions-answers.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: team-role-matrix.project-summary.nonMember - description: "@treeseed/admin project/question/search-questions-answers negative verifier backed by API acceptance case team-role-matrix.project-summary.nonMember." - admin.workday.workday.analyze-workday.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/analyze-workday api verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.analyze-workday.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/analyze-workday audit verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.analyze-workday.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/analyze-workday content verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.analyze-workday.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.diagnostics.inspect-mode-run-trace - description: "@treeseed/admin workday/workday/analyze-workday negative verifier backed by API acceptance case workday.diagnostics.inspect-mode-run-trace." - admin.workday.workday.monitor-workdays.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/monitor-workdays api verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.monitor-workdays.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/monitor-workdays audit verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.monitor-workdays.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/monitor-workdays content verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.monitor-workdays.negative: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.diagnostics.inspect-mode-run-trace - description: "@treeseed/admin workday/workday/monitor-workdays negative verifier backed by API acceptance case workday.diagnostics.inspect-mode-run-trace." - admin.workday.workday.schedule-workdays.api: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/schedule-workdays api verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.schedule-workdays.audit: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/schedule-workdays audit verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.schedule-workdays.content: - kind: apiAcceptanceCase - ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.artifacts.review-workday-artifacts - description: "@treeseed/admin workday/workday/schedule-workdays content verifier backed by API acceptance case workday.artifacts.review-workday-artifacts." - admin.workday.workday.schedule-workdays.negative: - kind: apiAcceptanceCase + testFile: tests/integration/api/teams/lifecycle/team-lifecycle.test.ts + testName: hides archived and deleted teams from anonymous profiles + api.team.public-profile.private-member-access: + kind: vitestCase ownerPackage: "@treeseed/api" - spec: scripts/api-acceptance.ts - caseId: workday.diagnostics.inspect-mode-run-trace - description: "@treeseed/admin workday/workday/schedule-workdays negative verifier backed by API acceptance case workday.diagnostics.inspect-mode-run-trace." + testFile: tests/integration/api/teams/lifecycle/team-lifecycle.test.ts + testName: hides private active profiles anonymously and restores member access after archival diff --git a/guarantees/verifiers/zz-composition.verifiers.yaml b/guarantees/verifiers/zz-composition.verifiers.yaml new file mode 100644 index 00000000..8ea74695 --- /dev/null +++ b/guarantees/verifiers/zz-composition.verifiers.yaml @@ -0,0 +1,207 @@ +schemaVersion: treeseed.guarantee-verifiers/v1 +ownerPackage: "@treeseed/admin" +verifiers: + admin.identity.onboarding: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.identity.onboarding + description: Reviewer executes the exact Admin registration and one-use email-confirmation scene in a real browser. + admin.identity.password-reset: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.identity.password-reset + admin.identity.login: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.identity.login + admin.identity.logout: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.identity.logout + admin.account.edit-profile: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.account.edit-profile + admin.account.sessions: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.account.sessions + admin.account.notifications: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.account.notifications + admin.account.appearance: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.account.appearance + admin.account.public-profile: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.account.public-profile + admin.account.delete: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.account.delete + admin.team.create: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.create + admin.team.select-active: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.select-active + admin.team.edit: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.edit + admin.team.overview: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.overview + admin.team.delete: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.delete + admin.team.invite: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.invite + admin.team.accept-invite: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.accept-invite + admin.team.change-member-role: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.change-member-role + admin.team.remove-member: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.remove-member + admin.team.public-profile: + kind: artifact + ownerPackage: "@treeseed/reviewer" + artifactId: "@treeseed/reviewer/admin-browser-scenes" + entrypoint: dist/verifiers/browser-scenes.js + caseId: admin.team.public-profile + admin.team.ui-contracts: &adminTeamUi + kind: artifact + ownerPackage: "@treeseed/admin" + artifactId: "@treeseed/admin/team-ui-contracts" + entrypoint: dist/standards/verifiers/team-ui-contracts.js + caseId: admin.team.ui-contracts + description: The packed Admin artifact retains catalog-driven team routes and shared submission behavior. + admin.identity-account.ui-contracts: + kind: artifact + ownerPackage: "@treeseed/admin" + artifactId: "@treeseed/admin/team-ui-contracts" + entrypoint: dist/standards/verifiers/team-ui-contracts.js + caseId: admin.identity-account.ui-contracts + description: The packed Admin artifact retains shared Identity redirects and callback, contact-email confirmation, CSRF-safe app logout, and delegated account management without local password forms. + sdk.team.ui-evidence-trust: + kind: artifact + ownerPackage: "@treeseed/sdk" + artifactId: "@treeseed/sdk/guarantee-verifier-contract" + entrypoint: dist/guarantees/index.js + exportName: runUiEvidenceTrustVerifier + caseId: sdk.ui.evidence-trust + description: The packed SDK rejects device substitution and unexpected console or transport failures. + api.auth.lifecycle.audit: + kind: artifact + ownerPackage: "@treeseed/api" + artifactId: "@treeseed/api/identity-team-verifier" + entrypoint: dist/standards/verifiers/identity-team-live.js + caseId: api.identity.audit-evidence + description: The exact API artifact correlates canonical durable identity, session, account, and team audit events to its disposable run records. + api.auth.signup.mailpit: &apiRegistration + kind: artifact + ownerPackage: "@treeseed/api" + artifactId: "@treeseed/api/identity-team-verifier" + entrypoint: dist/standards/verifiers/identity-team-live.js + caseId: api.identity.registration-confirmation-oauth + description: The exact API artifact proves registration, one-use confirmation, OAuth consent, PKCE, and replay rejection. + api.auth.signin: *apiRegistration + api.auth.email.lifecycle: *apiRegistration + api.auth.account-preferences: &apiAccount + kind: artifact + ownerPackage: "@treeseed/api" + artifactId: "@treeseed/api/identity-team-verifier" + entrypoint: dist/standards/verifiers/identity-team-live.js + caseId: api.identity.account-lifecycle + description: The exact API artifact proves account reads, mutations, preferences, sessions, reset, rotation, and replay rejection. + api.auth.account.blockers: *apiAccount + api.auth.appearance: *apiAccount + api.auth.me.requires-user: *apiAccount + api.auth.notifications: *apiAccount + api.auth.password-reset.request.mailpit: *apiAccount + api.auth.profile.update: *apiAccount + api.auth.public-knowledge-profile: *apiAccount + api.auth.sessions: *apiAccount + admin.team.production-readiness: &apiTeams + kind: artifact + ownerPackage: "@treeseed/api" + artifactId: "@treeseed/api/identity-team-verifier" + entrypoint: dist/standards/verifiers/identity-team-live.js + caseId: api.teams.lifecycle-authority-cleanup + description: The exact API artifact proves the team lifecycle, forbidden actors, concurrency, terminal invitations, last-owner protection, and cleanup. + api.team.accept.correlated: *apiTeams + api.team.active.correlated: *apiTeams + api.team.create.anonymous-denied: *apiTeams + api.team.create.correlated: *apiTeams + api.team.delete.correlated: *apiTeams + api.team.invitation.mismatch-denied: *apiTeams + api.team.invitation.terminal-states: *apiTeams + api.team.invite.contributor-denied: *apiTeams + api.team.invite.correlated: *apiTeams + api.team.lifecycle-contracts: *apiTeams + api.team.lifecycle.project-lead-denied: *apiTeams + api.team.overview.anonymous-denied: *apiTeams + api.team.overview.correlated: *apiTeams + api.team.overview.nonmember-denied: *apiTeams + api.team.public-profile.archived-not-found: *apiTeams + api.team.public-profile.correlated: *apiTeams + api.team.public-profile.private-member-access: *apiTeams + api.team.remove.contributor-denied: *apiTeams + api.team.remove.correlated: *apiTeams + api.team.role.contributor-denied: *apiTeams + api.team.role.correlated: *apiTeams + api.team.update.contributor-denied: *apiTeams + api.team.update.correlated: *apiTeams diff --git a/guarantees/work/agent-lab/monitor-agent-lab.guarantee.yaml b/guarantees/work/agent-lab/monitor-agent-lab.guarantee.yaml new file mode 100644 index 00000000..fc0b0469 --- /dev/null +++ b/guarantees/work/agent-lab/monitor-agent-lab.guarantee.yaml @@ -0,0 +1,22 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.work.agent-lab.monitor-agent-lab.035 +journeyIndex: 741 +type: work +subtype: agent-lab +journey: "Monitor the team Agent Lab" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "A team member sees one responsive, revisioned Agent Atlas for live operation and immutable historical replay, can inspect designed, assigned, and observed evidence, and can carry validated context into Discussion without granting historical state current mutation authority." +status: planned +dependencies: { journeys: [738], guarantees: [guarantee.work.command.monitor-team-operations.033] } +actors: { allowed: [authenticated_user, team_owner, project_lead], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium, tablet_chromium, mobile_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: ["An active team is selected and the API projection is available."] } +scene: { required: true, manifest: ../scenes/agent-lab-workspace-focus.scene.yaml, mode: { acceptance: true, demo: false, training: false }, expectedEvidence: [playwright_trace, screenshot_on_failure, console_log, network_log] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: ["Historical playback never substitutes current agent definitions and always identifies the exact immutable definition revision.", "Live events never force a historical cursor to the live edge.", "Absent recorded progress is never fabricated.", "A new topology revision never applies an incompatible saved viewport.", "Generated identity and runtime status cannot be edited as design intent.", "Provider supply cannot be widened from an agent definition.", "Simulation definitions never invent a provider identity or execution provider outside the reconciled project grant and provider inventory.", "The Agent Designer never invents metaphor-based controls or fields that are absent from the canonical Zod and API contracts.", "A project does not disappear from Agent authoring merely because it has no agents yet.", "Closing a URL-opened creator never allows live refresh to reopen it.", "A dirty Agent Designer never exits through Close, Escape, browser Back, or page unload without preserving the draft or receiving explicit discard confirmation.", "Easy Simulation Bay never renders generated source editors until the operator requests them.", "Designer, Simulation Bay, the admitted workday Atlas, and Return to Designer never lose the project, immutable definition, or originating inspection path.", "Historical Discussion context cannot authorize current execution.", "Advanced forensic fields never displace the primary human-readable content by default.", "Focusing Atlas never hides global TreeSeed navigation or changes the saved vital density.", "Shrinking a surface never remounts it or discards editor state.", "Escape and browser Back never close a parent before its top nested overlay.", "Easy mode never exposes protected diagnostic evidence.", "Portfolio mode never fits inactive historical topology revisions into the live canvas.", "The interactive event dock never renders an unbounded durable event collection.", "An empty Atlas never leaves the cause unexplained."] +evidence: { required: [guarantee_report] } +notes: ["The reusable Atlas implementation is present but remains planned until Easy/Diagnostic, overlay-first nested detail history, authoring conflicts, Discussion context, and production-shaped simulation workdays produce repeatable evidence.", "The Agent Designer interprets design/agent-manager.html through reusable @treeseed/ui components, while the canonical SDK Zod model and API authoring route remain authoritative over editable capabilities.", "The Build projection carries authorized project choices independently from configured agents so the supported template-first UI can create a project's first repository definition.", "Simulation Bay defaults to a compact readiness explanation; exact generated YAML and MDX remain available through an explicit source control or Diagnostic mode.", "A launched simulation opens its admitted workday in focused Atlas with the originating Designer return path and exact immutable definition revision; historical playback labels that revision as retained evidence.", "Focused Atlas must always expose Shrink while preserving the live or historical projection, viewport, dock, replay cursor, selection, and nested overlay stack.", "Desktop, tablet, and mobile scene runs must all prove expanded/compact vitals, bounded event filtering and paging, exact circuit replay/live return, inline/focused layout, Escape, browser Back, and state restoration.", "The standalone simulation viewer cannot be retired until integrated Atlas proves equivalent live, replay, evaluation, forensic, accessibility, responsive, and machine-readable evidence.", "The live portfolio embeds only a bounded recent event window with its exact durable total. Filters and paging are visible in the dock; complete evidence remains available through bounded forensic APIs and machine-readable CLI/tool surfaces."] diff --git a/guarantees/work/command/inspect-assignment.guarantee.yaml b/guarantees/work/command/inspect-assignment.guarantee.yaml new file mode 100644 index 00000000..5a552261 --- /dev/null +++ b/guarantees/work/command/inspect-assignment.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.work.command.inspect-assignment.034 +journeyIndex: 739 +type: work +subtype: command +journey: "Inspect an agent assignment" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "A team member can inspect matching, mode runs, artifacts, usage, errors, and eligible recovery controls for an assignment." +status: planned +dependencies: { journeys: [738], guarantees: [guarantee.work.command.monitor-team-operations.033] } +actors: { allowed: [authenticated_user, team_owner, project_lead], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: ["A durable assignment exists."] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: ["Ineligible cancel and requeue controls are hidden.", "Direct unauthorized mutations remain rejected."] +evidence: { required: [guarantee_report] } +notes: ["Planned until assignment inspection and failed-assignment visual scenes are repeatable."] diff --git a/guarantees/work/command/monitor-team-operations.guarantee.yaml b/guarantees/work/command/monitor-team-operations.guarantee.yaml new file mode 100644 index 00000000..d2d16eaf --- /dev/null +++ b/guarantees/work/command/monitor-team-operations.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.work.command.monitor-team-operations.033 +journeyIndex: 738 +type: work +subtype: command +journey: "Monitor team operations in Command" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "A team member can interpret situations and UI-owned live agent intervals while retaining the server snapshot and interaction state during refresh failure." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, project_lead], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: ["An active team is selected."] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: ["Hidden or offline documents stop polling.", "Refresh failure does not erase the server snapshot.", "Live updates never reload the page, move focus, or reset scroll and disclosure state."] +evidence: { required: [guarantee_report] } +notes: ["The Command activity field consumes the reusable UI Agent Activity Gantt and shared polling coordinator.", "Planned until active, idle, dense, failed, and appearance visual scenes are repeatable."] diff --git a/guarantees/work/focus/enter-focus-mode.guarantee.yaml b/guarantees/work/focus/enter-focus-mode.guarantee.yaml new file mode 100644 index 00000000..08b3d6f2 --- /dev/null +++ b/guarantees/work/focus/enter-focus-mode.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.work.focus.enter-focus-mode.031 +journeyIndex: 736 +type: work +subtype: focus +journey: "Enter the protected Focus mode" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "An authenticated team member can enter a stable research and governance snapshot without live polling." +status: planned +dependencies: { journeys: [], guarantees: [] } +actors: { allowed: [authenticated_user, team_owner, project_lead], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium, mobile_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: ["An active team is selected."] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: ["No timer, polling loop, or unrelated live region is mounted in Focus."] +evidence: { required: [guarantee_report] } +notes: ["Planned until local visual scenes cover every appearance scheme and narrow navigation."] diff --git a/guarantees/work/focus/review-governance.guarantee.yaml b/guarantees/work/focus/review-governance.guarantee.yaml new file mode 100644 index 00000000..b757ff15 --- /dev/null +++ b/guarantees/work/focus/review-governance.guarantee.yaml @@ -0,0 +1,21 @@ +schemaVersion: treeseed.guarantee/v1 +id: guarantee.work.focus.review-governance.032 +journeyIndex: 737 +type: work +subtype: focus +journey: "Review governance evidence in Focus" +ownerPackage: "@treeseed/admin" +surface: admin-ui +summary: "An authorized member can inspect proposal rationale, evidence, objections, consequences, and legal governance controls." +status: planned +dependencies: { journeys: [736], guarantees: [guarantee.work.focus.enter-focus-mode.031] } +actors: { allowed: [authenticated_user, team_owner, project_lead], forbidden: [unauthorized_user] } +devices: { required: [desktop_chromium] } +gates: [future] +preconditions: { fixtures: [integrated_treeseed_project], notes: ["A proposal exists."] } +api: { required: false, verifierRefs: [] } +content: { required: false, verifierRefs: [] } +audit: { required: false, verifierRefs: [] } +negativeCases: ["Unauthorized mutation remains rejected by the API."] +evidence: { required: [guarantee_report] } +notes: ["Planned until proposal review scene evidence is repeatable."] diff --git a/guarantees/work/scenes/agent-lab-workspace-focus.scene.yaml b/guarantees/work/scenes/agent-lab-workspace-focus.scene.yaml new file mode 100644 index 00000000..e7e7bcac --- /dev/null +++ b/guarantees/work/scenes/agent-lab-workspace-focus.scene.yaml @@ -0,0 +1,137 @@ +schemaVersion: treeseed.scene/v1 +id: agent-lab-workspace-focus +title: Agent Lab Workspace Focus +description: Verify vital density and Atlas content-region focus through the authenticated Agent Lab. +audience: [operator, designer, qa] +mode: { test: true, demo: false, training: false } +target: + app: market + environment: local + baseUrl: auto + browser: chromium + viewport: { width: 1600, height: 900 } +devices: + defaultProfile: desktop_chromium + profiles: + - { id: desktop_chromium, title: Desktop Chromium, orientation: landscape, viewport: { width: 1600, height: 900 }, video: { width: 1600, height: 900 }, output: { width: 1920, height: 1080 }, deviceScaleFactor: 1, isMobile: false, hasTouch: false } + - { id: tablet_chromium, title: Tablet Chromium, orientation: portrait, viewport: { width: 820, height: 1180 }, video: { width: 820, height: 1180 }, output: { width: 820, height: 1180 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } + - { id: mobile_chromium, title: Mobile Chromium, orientation: portrait, viewport: { width: 390, height: 844 }, video: { width: 390, height: 844 }, output: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true } +setup: + dev: { required: true, reuseExisting: true } + auth: { role: admin, required: true, seedOnly: true } +artifacts: { trace: true, video: false, screenshots: true, console: true, network: true, timeline: true, appLogs: true } +runtime: + mode: acceptance + failure: { continueOnFailure: false } + checkpoints: { enabled: false } +chapters: + - { id: authentication, title: Enter the team Agent Lab, startsAt: open-sign-in } + - { id: workspace-focus, title: Verify focus and navigation state, startsAt: wait-for-atlas } +workflow: + - id: open-sign-in + title: Open Agent Lab sign in + action: { goto: /auth/sign-in?returnTo=/app/work } + expect: { urlIncludes: /auth/sign-in } + - id: enter-login + title: Enter visual-audit administrator + action: { fill: { css: '#login', internal: true, value: visual.admin@treeseed.io } } + - id: enter-password + title: Enter visual-audit password + action: { fill: { css: '#password', internal: true, value: TreeSeedVisualAudit!2026 } } + - id: sign-in + title: Sign in to Agent Lab + action: { click: { role: button, name: Sign in } } + expect: { urlIncludes: /app/work } + - id: choose-team + title: Choose the visual-audit team + action: { select: { css: '.ts-product-shell__desktop-operations [data-team-switcher] select[name="teamId"]', internal: true, label: Acceptance visual-audit } } + - id: wait-for-atlas + title: Wait for the team Atlas + action: { pause: { mode: timed, durationSeconds: 2 } } + expect: + text: Visual Audit Agent + visible: + - { css: '[data-scene="agent-lab.atlas"]', internal: true } + - { css: '[data-atlas-selectable][aria-label^="Visual Audit Agent,"]', internal: true } + - id: compress-vitals + title: Toggle the persisted vital-statistics density + action: { click: { css: '.ts-operations-density', internal: true } } + expect: + visible: + - { css: '.ts-operations-density[aria-expanded]', internal: true } + - id: page-events-forward + title: Page through the bounded event log + action: { click: { role: button, name: Next } } + expect: { text: Page 2 of 2 } + - id: page-events-back + title: Return to the first event page + action: { click: { role: button, name: Previous } } + expect: { text: Page 1 of 2 } + - id: filter-events + title: Filter the event log by forensic evidence text + action: { fill: { css: '.ts-atlas-filters input[placeholder="Agent, project, or event"]', internal: true, value: forensic event 26 } } + expect: { text: 1 matching event } + - id: select-event-filter + title: Select the active event search + action: { keyboard: Control+A } + - id: clear-event-filter + title: Restore the complete bounded event window + action: { keyboard: Backspace } + expect: { text: 27 matching events } + - id: replay-from-start + title: Freeze the workday circuit at its first recorded instant + action: { click: { role: button, name: Stop and return to start } } + expect: + visible: + - { css: '[data-scene="agent-lab.atlas"][data-mode="historical"]', internal: true } + - id: inspect-historical-agent + title: Inspect the definition retained by historical playback + action: { click: { css: '[data-atlas-selectable][aria-label^="Visual Audit Agent,"]', internal: true } } + expect: + text: Historical definition + visible: + - { css: '[data-scene="agent-lab.definition-provenance"][data-mode="historical"]', internal: true } + - id: close-historical-agent + title: Return to the historical circuit + action: { click: { role: button, name: Close detail } } + expect: + visible: + - { css: '[data-scene="agent-lab.atlas"][data-mode="historical"]', internal: true } + - id: return-to-live-edge + title: Return the same circuit to its live edge + action: { click: { css: '.ts-atlas-live-edge', internal: true } } + expect: + visible: + - { css: '[data-scene="agent-lab.atlas"][data-mode="live"]', internal: true } + - id: expand-atlas + title: Focus Atlas across the Agent Lab content region + action: { click: { role: button, name: Expand Agent Atlas } } + expect: + urlIncludes: focus=atlas + visible: + - { css: '[data-workspace-surface="agent-atlas"][data-mode="focused"]', internal: true } + - { role: button, name: Shrink Agent Atlas } + - id: escape-focus + title: Shrink Atlas with Escape + action: { keyboard: Escape } + expect: + visible: + - { css: '[data-workspace-surface="agent-atlas"][data-mode="inline"]', internal: true } + - { role: button, name: Expand Agent Atlas } + - id: expand-atlas-for-history + title: Focus Atlas for browser history verification + action: { click: { role: button, name: Expand Agent Atlas } } + expect: { urlIncludes: focus=atlas } + - id: browser-back-focus + title: Shrink Atlas through browser Back + action: { browserHistory: back } + expect: + visible: + - { css: '[data-workspace-surface="agent-atlas"][data-mode="inline"]', internal: true } + - { role: button, name: Expand Agent Atlas } + - id: restore-vitals + title: Restore the persisted vital-statistics density + action: { click: { css: '.ts-operations-density', internal: true } } + expect: + visible: + - { css: '.ts-operations-density[aria-expanded]', internal: true } diff --git a/guarantees/workday/workday/analyze-workday.guarantee.yaml b/guarantees/workday/workday/analyze-workday.guarantee.yaml deleted file mode 100644 index a1d99093..00000000 --- a/guarantees/workday/workday/analyze-workday.guarantee.yaml +++ /dev/null @@ -1,79 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.workday.workday.analyze-workday.064 -journeyIndex: 64 -type: workday -subtype: workday -journey: Analyze Workday -ownerPackage: "@treeseed/admin" -summary: Summarize reports diagnostics artifacts decisions questions and usage after a workday; reports belong in .treeseed/workday-reports while content artifacts stay in collections. -status: active -dependencies: - journeys: - - 27 - - 28 - - 32 - guarantees: - - guarantee.capacity.capacity.approve-capacity.027 - - guarantee.capacity.capacity.deploy-capacity.028 - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - agent_operator - - capacity_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 27, 28, 32" -scene: - required: true - manifest: ./scenes/analyze-workday.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/workdays/seed-workday - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.workday.workday.analyze-workday.api -content: - required: false - verifierRefs: - - admin.workday.workday.analyze-workday.content -audit: - required: true - verifierRefs: - - admin.workday.workday.analyze-workday.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.workday.workday.analyze-workday.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Summarize reports diagnostics artifacts decisions questions and usage after a workday; reports belong in .treeseed/workday-reports while content artifacts stay in collections. diff --git a/guarantees/workday/workday/monitor-workdays.guarantee.yaml b/guarantees/workday/workday/monitor-workdays.guarantee.yaml deleted file mode 100644 index 8a709549..00000000 --- a/guarantees/workday/workday/monitor-workdays.guarantee.yaml +++ /dev/null @@ -1,79 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.workday.workday.monitor-workdays.063 -journeyIndex: 63 -type: workday -subtype: workday -journey: Monitor Workdays -ownerPackage: "@treeseed/admin" -summary: Track live workday assignments mode runs generated artifacts usage and settlement; should continue scheduling useful planning work while budget and time remain. -status: active -dependencies: - journeys: - - 27 - - 28 - - 32 - guarantees: - - guarantee.capacity.capacity.approve-capacity.027 - - guarantee.capacity.capacity.deploy-capacity.028 - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - agent_operator - - capacity_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 27, 28, 32" -scene: - required: true - manifest: ./scenes/monitor-workdays.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/capacity/workday-runs - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.workday.workday.monitor-workdays.api -content: - required: false - verifierRefs: - - admin.workday.workday.monitor-workdays.content -audit: - required: true - verifierRefs: - - admin.workday.workday.monitor-workdays.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.workday.workday.monitor-workdays.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Track live workday assignments mode runs generated artifacts usage and settlement; should continue scheduling useful planning work while budget and time remain. diff --git a/guarantees/workday/workday/scenes/analyze-workday.scene.yaml b/guarantees/workday/workday/scenes/analyze-workday.scene.yaml deleted file mode 100644 index b481ca95..00000000 --- a/guarantees/workday/workday/scenes/analyze-workday.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: workday.workday.analyze-workday.064 -title: Analyze Workday -description: Scene scaffold for guarantee.workday.workday.analyze-workday.064. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Analyze Workday opens the canonical @treeseed/admin record operations workflow. - - Analyze Workday exercises a service journey instead of only loading /app/projects/project-visual-audit-project/workdays/seed-workday. - - Analyze Workday records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Analyze Workday - action: - goto: /app/projects/project-visual-audit-project/workdays/seed-workday - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Analyze Workday service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/workday/workday/scenes/monitor-workdays.scene.yaml b/guarantees/workday/workday/scenes/monitor-workdays.scene.yaml deleted file mode 100644 index 5aa1b080..00000000 --- a/guarantees/workday/workday/scenes/monitor-workdays.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: workday.workday.monitor-workdays.063 -title: Monitor Workdays -description: Scene scaffold for guarantee.workday.workday.monitor-workdays.063. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Monitor Workdays opens the canonical @treeseed/admin record operations workflow. - - Monitor Workdays exercises a service journey on the canonical workday run operator surface. - - Monitor Workdays records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Monitor Workdays - action: - goto: /app/capacity/workday-runs - expect: - urlIncludes: /app/capacity/workday-runs - - id: inspect-service-surface - title: Inspect Monitor Workdays service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/capacity/workday-runs -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/workday/workday/scenes/schedule-workdays.scene.yaml b/guarantees/workday/workday/scenes/schedule-workdays.scene.yaml deleted file mode 100644 index 28f72be3..00000000 --- a/guarantees/workday/workday/scenes/schedule-workdays.scene.yaml +++ /dev/null @@ -1,118 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: workday.workday.schedule-workdays.062 -title: Schedule Workdays -description: Scene scaffold for guarantee.workday.workday.schedule-workdays.062. This scene is intentionally minimal until the workflow-specific acceptance steps are authored. -audience: - - operator - - evaluator -journey: - kind: service - proves: - - Schedule Workdays opens the canonical @treeseed/admin record operations workflow. - - Schedule Workdays exercises a service journey instead of only loading /app/projects/project-visual-audit-project/workdays. - - Schedule Workdays records reviewable evidence for the visible result before activation. - minimumSteps: 2 - requiresInteractiveAction: true - consumesState: - - key: auth.owner - kind: user - - key: project.primary - kind: project -mode: - test: true - demo: true - training: true -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true -workflow: - - id: open-entry-route - title: Open Schedule Workdays - action: - goto: /app/projects/project-visual-audit-project/workdays - expect: - urlIncludes: /app/projects - - id: inspect-service-surface - title: Inspect Schedule Workdays service surface - action: - keyboard: Tab - expect: - urlIncludes: /app/projects -chapters: [] -overlays: [] -diagrams: [] -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser -runtime: - mode: training - timeouts: - sceneSeconds: 300 - chapterSeconds: 120 - stepSeconds: 60 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: false -training: - formats: - - json - - markdown - - vtt - - srt -visualAudit: - enabled: false diff --git a/guarantees/workday/workday/schedule-workdays.guarantee.yaml b/guarantees/workday/workday/schedule-workdays.guarantee.yaml deleted file mode 100644 index bc3aba27..00000000 --- a/guarantees/workday/workday/schedule-workdays.guarantee.yaml +++ /dev/null @@ -1,79 +0,0 @@ -schemaVersion: treeseed.guarantee/v1 -id: guarantee.workday.workday.schedule-workdays.062 -journeyIndex: 62 -type: workday -subtype: workday -journey: Schedule Workdays -ownerPackage: "@treeseed/admin" -summary: Create duration and budget bounded workdays for projects with approved capacity; planning must cover eligible agents before repeats. -status: active -dependencies: - journeys: - - 27 - - 28 - - 32 - guarantees: - - guarantee.capacity.capacity.approve-capacity.027 - - guarantee.capacity.capacity.deploy-capacity.028 - - guarantee.project.project.create-project.032 -actors: - allowed: - - project_manager - - agent_operator - - capacity_operator - forbidden: - - anonymous_user - - unauthorized_user -devices: - required: - - desktop_chromium - - desktop_firefox - - tablet_chromium -gates: - - core - - release -preconditions: - fixtures: - - integrated_treeseed_project - notes: - - "Journey dependencies must be satisfied: 27, 28, 32" -scene: - required: true - manifest: ./scenes/schedule-workdays.scene.yaml - mode: - acceptance: true - demo: true - training: true - entryRoute: /app/projects/project-visual-audit-project/workdays - componentContract: dashboard/read-model service journey - expectedEvidence: - - playwright_trace - - scene_video - - screenshot_on_failure - - console_log - - network_log -api: - required: true - verifierRefs: - - admin.workday.workday.schedule-workdays.api -content: - required: false - verifierRefs: - - admin.workday.workday.schedule-workdays.content -audit: - required: true - verifierRefs: - - admin.workday.workday.schedule-workdays.audit -negativeCases: - - id: unauthorized-actor-denied - actor: anonymous_user - verifierRefs: - - admin.workday.workday.schedule-workdays.negative -evidence: - required: - - playwright_trace - - scene_video - - api_verification_log - - audit_event_id -notes: - - Create duration and budget bounded workdays for projects with approved capacity; planning must cover eligible agents before repeats. diff --git a/package-lock.json b/package-lock.json index 0079ea27..b6beeefe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,38 +1,43 @@ { "name": "@treeseed/admin", - "version": "0.12.58", + "version": "0.12.59-rc.38", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@treeseed/admin", - "version": "0.12.58", - "license": "AGPL-3.0-only", + "version": "0.12.59-rc.38", + "license": "Apache-2.0", "dependencies": { - "@mdxeditor/editor": "^4.0.2", - "@react-email/render": "^2.0.8", - "@treeseed/core": "0.12.59", - "@treeseed/sdk": "0.12.62", - "@treeseed/ui": "0.12.17", - "libsodium-wrappers-sumo": "^0.7.16", + "@astrojs/starlight": "0.37.6", + "@treeseed/core": ">=0.12.60-rc.1 <0.14.0", + "@treeseed/identity": "0.1.0-rc.13", + "@treeseed/sdk": "0.13.0-rc.107", + "@treeseed/ui": "0.12.18-rc.20", + "jose": "6.2.12", "react": "^19.2.5", "react-dom": "^19.2.6" }, + "bin": { + "treeseed-admin-verify-team-ui": "dist/standards/verifiers/team-ui-contracts.js" + }, "devDependencies": { + "@astrojs/cloudflare": "12.6.13", "@types/node": "^24.6.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "astro": "^6.4.5", + "astro": "^5.6.1", "esbuild": "^0.28.0", "tsx": "^4.21.0", "typescript": "^5.9.3", - "vitest": "^4.1.2" + "vitest": "^4.1.2", + "yaml": "^2.9.0" }, "engines": { "node": ">=22" }, "peerDependencies": { - "astro": "^5.0.0 || ^6.0.0" + "astro": "^5.0.0" } }, "node_modules/@alcalzone/ansi-tokenize": { @@ -40,6 +45,7 @@ "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.3.0.tgz", "integrity": "sha512-p+CMKJ93HFmLkjXKlXiVGlMQEuRb6H0MokBSwUsX+S6BRX8eV5naFZpQJFfJHjRZY0Hmnqy1/r6UWl3x+19zYA==", "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" @@ -49,15 +55,15 @@ } }, "node_modules/@astrojs/check": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.9.tgz", - "integrity": "sha512-A5UW8uIuErLWEoRQvzgXpO1gTjUFtK8r7nU2Z7GewAMxUb7bPvpk11qaKKgxqXlHJWlAvaaxy+Xg28A6bmQ1Tg==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.10.tgz", + "integrity": "sha512-zgx/UQMozdjOa3bOxjgeCFdtpE3c9rRX6xHwa+2QXvy8z8Akifu2AtubHyv/zzC2znO8dl8fFWL4K+Ba9kS8HQ==", "license": "MIT", "dependencies": { "@astrojs/language-server": "^2.16.7", "chokidar": "^4.0.3", "kleur": "^4.1.5", - "yargs": "^17.7.2" + "yargs": "^18.0.0" }, "bin": { "astro-check": "bin/astro-check.js" @@ -66,121 +72,125 @@ "typescript": "^5.0.0 || ^6.0.0" } }, - "node_modules/@astrojs/compiler": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", - "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", - "license": "MIT" - }, - "node_modules/@astrojs/internal-helpers": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.6.tgz", - "integrity": "sha512-GOle7smBWKfMSP8osUIGOlB5kaHdQLV3foCsf+5Q9Wsuu+C6Fs3Ez/ttXmhjZ1HkSgsogcM1RXSjjOVieHq16Q==", - "license": "MIT" - }, - "node_modules/@astrojs/language-server": { - "version": "2.16.11", - "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.11.tgz", - "integrity": "sha512-sJ/EfnFp0+gurTrkvONtd9qRqmMZLT9bHelfI1SA35CaQVTrRrA74qteOcNT/al1b9Atg3IiH1Jk/qfckyC+fg==", + "node_modules/@astrojs/cloudflare": { + "version": "12.6.13", + "resolved": "https://registry.npmjs.org/@astrojs/cloudflare/-/cloudflare-12.6.13.tgz", + "integrity": "sha512-oKaCyiovyQr183r9U93787Ju1zwk+rRMgPnLTwCLckHmOUK7sltA1Gp4LSGt8oNMgqQS6jR7uRdfQ/NPul37QA==", "license": "MIT", "dependencies": { - "@astrojs/compiler": "^2.13.1", - "@astrojs/yaml2ts": "^0.2.4", - "@jridgewell/sourcemap-codec": "^1.5.5", - "@volar/kit": "~2.4.28", - "@volar/language-core": "~2.4.28", - "@volar/language-server": "~2.4.28", - "@volar/language-service": "~2.4.28", - "muggle-string": "^0.4.1", - "tinyglobby": "^0.2.16", - "volar-service-css": "0.0.71", - "volar-service-emmet": "0.0.71", - "volar-service-html": "0.0.71", - "volar-service-prettier": "0.0.71", - "volar-service-typescript": "0.0.71", - "volar-service-typescript-twoslash-queries": "0.0.71", - "volar-service-yaml": "0.0.71", - "vscode-html-languageservice": "^5.6.2", - "vscode-uri": "^3.1.0" - }, - "bin": { - "astro-ls": "bin/nodeServer.js" + "@astrojs/internal-helpers": "0.7.6", + "@astrojs/underscore-redirects": "1.0.0", + "@cloudflare/workers-types": "^4.20260116.0", + "tinyglobby": "^0.2.15", + "vite": "^6.4.1", + "wrangler": "4.59.2" }, "peerDependencies": { - "prettier": "^3.0.0", - "prettier-plugin-astro": ">=0.11.0" + "astro": "^5.7.0" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/unenv-preset": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.10.0.tgz", + "integrity": "sha512-/uII4vLQXhzCAZzEVeYAjFLBNg2nqTJ1JGzd2lRF6ItYe6U2zVoYGfeKpGx/EkBF6euiU+cyBXgMdtJih+nQ6g==", + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": "^1.20251221.0" }, "peerDependenciesMeta": { - "prettier": { - "optional": true - }, - "prettier-plugin-astro": { + "workerd": { "optional": true } } }, - "node_modules/@astrojs/markdown-remark": { - "version": "6.3.11", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.11.tgz", - "integrity": "sha512-hcaxX/5aC6lQgHeGh1i+aauvSwIT6cfyFjKWvExYSxUhZZBBdvCliOtu06gbQyhbe0pGJNoNmqNlQZ5zYUuIyQ==", - "license": "MIT", - "dependencies": { - "@astrojs/internal-helpers": "0.7.6", - "@astrojs/prism": "3.3.0", - "github-slugger": "^2.0.0", - "hast-util-from-html": "^2.0.3", - "hast-util-to-text": "^4.0.2", - "import-meta-resolve": "^4.2.0", - "js-yaml": "^4.1.1", - "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^7.0.0", - "rehype-stringify": "^10.0.1", - "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.2", - "remark-smartypants": "^3.0.2", - "shiki": "^3.21.0", - "smol-toml": "^1.6.0", - "unified": "^11.0.5", - "unist-util-remove-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "unist-util-visit-parents": "^6.0.2", - "vfile": "^6.0.3" + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20260114.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260114.0.tgz", + "integrity": "sha512-HNlsRkfNgardCig2P/5bp/dqDECsZ4+NU5XewqArWxMseqt3C5daSuptI620s4pn7Wr0ZKg7jVLH0PDEBkA+aA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" } }, - "node_modules/@astrojs/prism": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", - "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", - "license": "MIT", - "dependencies": { - "prismjs": "^1.30.0" - }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20260114.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260114.0.tgz", + "integrity": "sha512-qyE1UdFnAlxzb+uCfN/d9c8icch7XRiH49/DjoqEa+bCDihTuRS7GL1RmhVIqHJhb3pX3DzxmKgQZBDBL83Inw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" + "node": ">=16" } }, - "node_modules/@astrojs/react": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-4.4.2.tgz", - "integrity": "sha512-1tl95bpGfuaDMDn8O3x/5Dxii1HPvzjvpL2YTuqOOrQehs60I2DKiDgh1jrKc7G8lv+LQT5H15V6QONQ+9waeQ==", - "license": "MIT", - "dependencies": { - "@vitejs/plugin-react": "^4.7.0", - "ultrahtml": "^1.6.0", - "vite": "^6.4.1" - }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20260114.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260114.0.tgz", + "integrity": "sha512-Z0BLvAj/JPOabzads2ddDEfgExWTlD22pnwsuNbPwZAGTSZeQa3Y47eGUWyHk+rSGngknk++S7zHTGbKuG7RRg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" - }, - "peerDependencies": { - "@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0", - "@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0", - "react": "^17.0.2 || ^18.0.0 || ^19.0.0", - "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0" + "node": ">=16" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/aix-ppc64": { + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20260114.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260114.0.tgz", + "integrity": "sha512-kPUmEtUxUWlr9PQ64kuhdK0qyo8idPe5IIXUgi7xCD7mDd6EOe5J7ugDpbfvfbYKEjx4DpLvN2t45izyI/Sodw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20260114.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260114.0.tgz", + "integrity": "sha512-MJnKgm6i1jZGyt2ZHQYCnRlpFTEZcK2rv9y7asS3KdVEXaDgGF8kOns5u6YL6/+eMogfZuHRjfDS+UqRTUYIFA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workers-types": { + "version": "4.20260702.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz", + "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==", + "license": "MIT OR Apache-2.0" + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", @@ -196,7 +206,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/android-arm": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", @@ -212,7 +222,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/android-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", @@ -228,7 +238,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/android-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", @@ -244,7 +254,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/darwin-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", @@ -260,7 +270,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/darwin-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", @@ -276,7 +286,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/freebsd-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", @@ -292,7 +302,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/freebsd-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", @@ -308,7 +318,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-arm": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", @@ -324,7 +334,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", @@ -340,7 +350,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-ia32": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ia32": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", @@ -356,7 +366,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-loong64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-loong64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", @@ -372,7 +382,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-mips64el": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-mips64el": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", @@ -388,7 +398,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-ppc64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", @@ -404,7 +414,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-riscv64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-riscv64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", @@ -420,7 +430,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-s390x": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-s390x": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", @@ -436,7 +446,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/linux-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", @@ -452,7 +462,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/netbsd-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", @@ -468,7 +478,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/netbsd-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", @@ -484,7 +494,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/openbsd-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", @@ -500,7 +510,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/openbsd-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", @@ -516,7 +526,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/openharmony-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openharmony-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", @@ -532,7 +542,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/sunos-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/sunos-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", @@ -548,7 +558,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/win32-arm64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", @@ -564,7 +574,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/win32-ia32": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-ia32": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", @@ -580,7 +590,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@esbuild/win32-x64": { + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", @@ -596,33 +606,7 @@ "node": ">=18" } }, - "node_modules/@astrojs/react/node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", - "license": "MIT" - }, - "node_modules/@astrojs/react/node_modules/@vitejs/plugin-react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", - "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.28.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/@astrojs/react/node_modules/esbuild": { + "node_modules/@astrojs/cloudflare/node_modules/esbuild": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", @@ -663,30 +647,37 @@ "@esbuild/win32-x64": "0.25.12" } }, - "node_modules/@astrojs/react/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, + "node_modules/@astrojs/cloudflare/node_modules/miniflare": { + "version": "4.20260114.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260114.0.tgz", + "integrity": "sha512-QwHT7S6XqGdQxIvql1uirH/7/i3zDEt0B/YBXTYzMfJtVCR4+ue3KPkU+Bl0zMxvpgkvjh9+eCHhJbKEqya70A==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "sharp": "^0.34.5", + "undici": "7.14.0", + "workerd": "1.20260114.0", + "ws": "8.18.0", + "youch": "4.1.0-beta.10", + "zod": "^3.25.76" + }, + "bin": { + "miniflare": "bootstrap.js" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=18.0.0" } }, - "node_modules/@astrojs/react/node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "node_modules/@astrojs/cloudflare/node_modules/undici": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.14.0.tgz", + "integrity": "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=20.18.1" } }, - "node_modules/@astrojs/react/node_modules/vite": { + "node_modules/@astrojs/cloudflare/node_modules/vite": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", @@ -760,1810 +751,1709 @@ } } }, - "node_modules/@astrojs/sitemap": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", - "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", - "license": "MIT", - "dependencies": { - "sitemap": "^8.0.2", - "stream-replace-string": "^2.0.0", - "zod": "^3.25.76" + "node_modules/@astrojs/cloudflare/node_modules/workerd": { + "version": "1.20260114.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260114.0.tgz", + "integrity": "sha512-kTJ+jNdIllOzWuVA3NRQRvywP0T135zdCjAE2dAUY1BFbxM6fmMZV8BbskEoQ4hAODVQUfZQmyGctcwvVCKxFA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20260114.0", + "@cloudflare/workerd-darwin-arm64": "1.20260114.0", + "@cloudflare/workerd-linux-64": "1.20260114.0", + "@cloudflare/workerd-linux-arm64": "1.20260114.0", + "@cloudflare/workerd-windows-64": "1.20260114.0" } }, - "node_modules/@astrojs/telemetry": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.2.tgz", - "integrity": "sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==", - "license": "MIT", + "node_modules/@astrojs/cloudflare/node_modules/wrangler": { + "version": "4.59.2", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.59.2.tgz", + "integrity": "sha512-Z4xn6jFZTaugcOKz42xvRAYKgkVUERHVbuCJ5+f+gK+R6k12L02unakPGOA0L0ejhUl16dqDjKe4tmL9sedHcw==", + "license": "MIT OR Apache-2.0", "dependencies": { - "ci-info": "^4.4.0", - "dset": "^3.1.4", - "is-docker": "^4.0.0", - "is-wsl": "^3.1.1", - "which-pm-runs": "^1.1.0" + "@cloudflare/kv-asset-handler": "0.4.2", + "@cloudflare/unenv-preset": "2.10.0", + "blake3-wasm": "2.1.5", + "esbuild": "0.27.0", + "miniflare": "4.20260114.0", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.24", + "workerd": "1.20260114.0" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" }, "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" + "node": ">=20.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20260114.0" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } } }, - "node_modules/@astrojs/underscore-redirects": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-1.0.0.tgz", - "integrity": "sha512-qZxHwVnmb5FXuvRsaIGaqWgnftjCuMY+GSbaVZdBmE4j8AfgPqKPxYp8SUERyJcjpKCEmO4wD6ybuGH8A2kVRQ==", - "license": "MIT" - }, - "node_modules/@astrojs/yaml2ts": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.4.tgz", - "integrity": "sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "yaml": "^2.8.3" + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@babel/code-frame": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", - "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/android-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.29.7", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/compat-data": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", - "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/android-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/core": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", - "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/android-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.7", - "@babel/helper-compilation-targets": "^7.29.7", - "@babel/helper-module-transforms": "^7.29.7", - "@babel/helpers": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/template": "^7.29.7", - "@babel/traverse": "^7.29.7", - "@babel/types": "^7.29.7", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">=18" } }, - "node_modules/@babel/generator": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", - "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", - "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/darwin-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", + "cpu": [ + "x64" + ], "license": "MIT", - "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" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, - "node_modules/@babel/helper-globals": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", - "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", + "cpu": [ + "arm" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", - "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.29.7", - "@babel/types": "^7.29.7" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", - "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7", - "@babel/traverse": "^7.29.7" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", - "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-loong64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", + "cpu": [ + "loong64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", - "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", + "cpu": [ + "mips64el" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", + "cpu": [ + "ppc64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", - "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", + "cpu": [ + "riscv64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helpers": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", - "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-s390x": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", + "cpu": [ + "s390x" + ], "license": "MIT", - "dependencies": { - "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.7" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", - "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", - "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/template": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", - "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", - "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.7", - "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@capsizecss/unpack": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.1.tgz", - "integrity": "sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==", - "license": "MIT", - "dependencies": { - "fontkitten": "^1.0.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@clack/core": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.4.3.tgz", - "integrity": "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==", - "license": "MIT", - "dependencies": { - "fast-wrap-ansi": "^0.2.0", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 20.12.0" - } - }, - "node_modules/@clack/prompts": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.7.0.tgz", - "integrity": "sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==", - "license": "MIT", - "dependencies": { - "@clack/core": "1.4.3", - "fast-string-width": "^3.0.2", - "fast-wrap-ansi": "^0.2.0", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 20.12.0" - } - }, - "node_modules/@cloudflare/kv-asset-handler": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz", - "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==", - "license": "MIT OR Apache-2.0", - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@cloudflare/unenv-preset": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz", - "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==", - "license": "MIT OR Apache-2.0", - "peerDependencies": { - "unenv": "2.0.0-rc.24", - "workerd": ">1.20260305.0 <2.0.0-0" - }, - "peerDependenciesMeta": { - "workerd": { - "optional": true - } - } - }, - "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20260708.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260708.1.tgz", - "integrity": "sha512-HXFCvhS1wpg3uXO0CLUwmwC41i2loM5FSK69EUchOBpmYBAXxT1oHLm6EOA5lqhTk5Mu9kjRiQYxa1GwKPwfJg==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", "cpu": [ "x64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "darwin" + "openbsd" ], "engines": { - "node": ">=16" + "node": ">=18" } }, - "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20260708.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260708.1.tgz", - "integrity": "sha512-JVlJaKDoRTVKSroHIlf8g3UCPjKj4iDbMZE2CNYht5qQ+2rL0FAUiVlV82G3BqKnnw9kHYnnsMzC08b9zVtdzA==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", "cpu": [ "arm64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "darwin" + "openharmony" ], "engines": { - "node": ">=16" + "node": ">=18" } }, - "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20260708.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260708.1.tgz", - "integrity": "sha512-3daE60YdD7YX0Jtuzc9DE/r/qMkmx8ZvHTkF8Mzmp3F5tbzlV0DAzmu5PFUPF2WuvtKbAhZKbvC2cHmWpQYxnA==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/sunos-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", "cpu": [ "x64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" + "sunos" ], "engines": { - "node": ">=16" + "node": ">=18" } }, - "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20260708.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260708.1.tgz", - "integrity": "sha512-VLdNYOx5Hj+9C6isy0ACWZsbMtSxex2DIJWEe7cZxUdlphZ58ZT8zxNXK8yunFiowd34hn3VwGMopdvdj8lvmA==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/win32-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", "cpu": [ "arm64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { - "node": ">=16" + "node": ">=18" } }, - "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20260708.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260708.1.tgz", - "integrity": "sha512-bC/aSAwLy16Vjo24i9XU3aWH+eRgz7NeR5xPKavGbembO18ZywYTQbXh14eXtY6fAqN3RzRG8psijTdhX4xydA==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/win32-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", "cpu": [ - "x64" + "ia32" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=16" + "node": ">=18" } }, - "node_modules/@codemirror/autocomplete": { - "version": "6.20.3", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.3.tgz", - "integrity": "sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/win32-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.17.0", - "@lezer/common": "^1.0.0" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/commands": { - "version": "6.10.4", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.4.tgz", - "integrity": "sha512-Ryk9y9T0FFVF0cUGhAknveAyUOl/A1qReTFi+qPKtOh2Z9F4AUBz3XOrYD4ZEgZirdugVzHvd/2/Wcwy5OliTg==", + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/esbuild": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.7.0", - "@codemirror/view": "^6.27.0", - "@lezer/common": "^1.1.0" + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" } }, - "node_modules/@codemirror/lang-angular": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@codemirror/lang-angular/-/lang-angular-0.1.4.tgz", - "integrity": "sha512-oap+gsltb/fzdlTQWD6BFF4bSLKcDnlxDsLdePiJpCVNKWXSTAbiiQeYI3UmES+BLAdkmIC1WjyztC1pi/bX4g==", + "node_modules/@astrojs/cloudflare/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", - "dependencies": { - "@codemirror/lang-html": "^6.0.0", - "@codemirror/lang-javascript": "^6.1.2", - "@codemirror/language": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.3.3" + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/@codemirror/lang-cpp": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.3.tgz", - "integrity": "sha512-URM26M3vunFFn9/sm6rzqrBzDgfWuDixp85uTY49wKudToc2jTHUrKIGGKs+QWND+YLofNNZpxcNGRynFJfvgA==", - "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/cpp": "^1.0.0" - } + "node_modules/@astrojs/compiler": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", + "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", + "license": "MIT" }, - "node_modules/@codemirror/lang-css": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", - "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.6.tgz", + "integrity": "sha512-GOle7smBWKfMSP8osUIGOlB5kaHdQLV3foCsf+5Q9Wsuu+C6Fs3Ez/ttXmhjZ1HkSgsogcM1RXSjjOVieHq16Q==", + "license": "MIT" + }, + "node_modules/@astrojs/language-server": { + "version": "2.16.13", + "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.13.tgz", + "integrity": "sha512-ekOa+CYprEq5n4EJC1qTIAhLk49HZIUQuFwrEuF+3JK/pdMaYnWoREFUI2A0KEPOJiFA2kamBzKzbYljDvUxLg==", "license": "MIT", "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.0.2", - "@lezer/css": "^1.1.7" + "@astrojs/compiler": "^2.13.1", + "@astrojs/yaml2ts": "^0.2.4", + "@jridgewell/sourcemap-codec": "^1.5.5", + "@volar/kit": "~2.4.28", + "@volar/language-core": "~2.4.28", + "@volar/language-server": "~2.4.28", + "@volar/language-service": "~2.4.28", + "muggle-string": "^0.4.1", + "tinyglobby": "^0.2.16", + "volar-service-css": "0.0.71", + "volar-service-emmet": "0.0.71", + "volar-service-html": "0.0.71", + "volar-service-prettier": "0.0.71", + "volar-service-typescript": "0.0.71", + "volar-service-typescript-twoslash-queries": "0.0.71", + "volar-service-yaml": "0.0.71", + "vscode-html-languageservice": "^5.6.2", + "vscode-uri": "^3.1.0" + }, + "bin": { + "astro-ls": "bin/nodeServer.js" + }, + "peerDependencies": { + "prettier": "^3.0.0", + "prettier-plugin-astro": ">=0.11.0" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + } } }, - "node_modules/@codemirror/lang-go": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-go/-/lang-go-6.0.1.tgz", - "integrity": "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==", + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.11", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.11.tgz", + "integrity": "sha512-hcaxX/5aC6lQgHeGh1i+aauvSwIT6cfyFjKWvExYSxUhZZBBdvCliOtu06gbQyhbe0pGJNoNmqNlQZ5zYUuIyQ==", "license": "MIT", "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.6.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/go": "^1.0.0" + "@astrojs/internal-helpers": "0.7.6", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" } }, - "node_modules/@codemirror/lang-html": { - "version": "6.4.11", - "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.11.tgz", - "integrity": "sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==", + "node_modules/@astrojs/mdx": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.3.14.tgz", + "integrity": "sha512-FBrqJQORVm+rkRa2TS5CjU9PBA6hkhrwLVBSS9A77gN2+iehvjq1w6yya/d0YKC7osiVorKkr3Qd9wNbl0ZkGA==", "license": "MIT", "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/lang-css": "^6.0.0", - "@codemirror/lang-javascript": "^6.0.0", - "@codemirror/language": "^6.4.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.17.0", - "@lezer/common": "^1.0.0", - "@lezer/css": "^1.1.0", - "@lezer/html": "^1.3.12" + "@astrojs/markdown-remark": "6.3.11", + "@mdx-js/mdx": "^3.1.1", + "acorn": "^8.15.0", + "es-module-lexer": "^1.7.0", + "estree-util-visit": "^2.0.0", + "hast-util-to-html": "^9.0.5", + "piccolore": "^0.1.3", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.1", + "remark-smartypants": "^3.0.2", + "source-map": "^0.7.6", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.3" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + }, + "peerDependencies": { + "astro": "^5.0.0" } }, - "node_modules/@codemirror/lang-java": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.2.tgz", - "integrity": "sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ==", + "node_modules/@astrojs/mdx/node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/@astrojs/node": { + "version": "9.5.5", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.5.5.tgz", + "integrity": "sha512-rtU2BGU5u3SfGURpANfMxVzCIoR86MkaN05ncza9rbtuMKJ/XnRJt/BbyVknDbOJ71hoci0SIsJwKcJR8vvi/A==", "license": "MIT", "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/java": "^1.0.0" + "@astrojs/internal-helpers": "0.7.6", + "send": "^1.2.1", + "server-destroy": "^1.0.1" + }, + "peerDependencies": { + "astro": "^5.17.3" } }, - "node_modules/@codemirror/lang-javascript": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.5.tgz", - "integrity": "sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==", + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", "license": "MIT", "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.6.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.17.0", - "@lezer/common": "^1.0.0", - "@lezer/javascript": "^1.0.0" + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" } }, - "node_modules/@codemirror/lang-jinja": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-jinja/-/lang-jinja-6.0.1.tgz", - "integrity": "sha512-P5kyHLObzjtbGj16h+hyvZTxJhSjBEeSx4wMjbnAf3b0uwTy2+F0zGjMZL4PQOm/mh2eGZ5xUDVZXgwP783Nsw==", + "node_modules/@astrojs/react": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-4.4.2.tgz", + "integrity": "sha512-1tl95bpGfuaDMDn8O3x/5Dxii1HPvzjvpL2YTuqOOrQehs60I2DKiDgh1jrKc7G8lv+LQT5H15V6QONQ+9waeQ==", "license": "MIT", "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/lang-html": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.2.0", - "@lezer/lr": "^1.4.0" + "@vitejs/plugin-react": "^4.7.0", + "ultrahtml": "^1.6.0", + "vite": "^6.4.1" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + }, + "peerDependencies": { + "@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0", + "@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0", + "react": "^17.0.2 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@codemirror/lang-json": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz", - "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", + "node_modules/@astrojs/react/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/json": "^1.0.0" + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-less": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-less/-/lang-less-6.0.2.tgz", - "integrity": "sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==", + "node_modules/@astrojs/react/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "@codemirror/lang-css": "^6.2.0", - "@codemirror/language": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-liquid": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-liquid/-/lang-liquid-6.3.2.tgz", - "integrity": "sha512-6PDVU3ZnfeYyz1at1E/ttorErZvZFXXt1OPhtfe1EZJ2V2iDFa0CwPqPgG5F7NXN0yONGoBogKmFAafKTqlwIw==", + "node_modules/@astrojs/react/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/lang-html": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.3.1" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-markdown": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.5.0.tgz", - "integrity": "sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw==", + "node_modules/@astrojs/react/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@codemirror/autocomplete": "^6.7.1", - "@codemirror/lang-html": "^6.0.0", - "@codemirror/language": "^6.3.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.2.1", - "@lezer/markdown": "^1.0.0" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-php": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.2.tgz", - "integrity": "sha512-ZKy2v1n8Fc8oEXj0Th0PUMXzQJ0AIR6TaZU+PbDHExFwdu+guzOA4jmCHS1Nz4vbFezwD7LyBdDnddSJeScMCA==", + "node_modules/@astrojs/react/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@codemirror/lang-html": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/php": "^1.0.0" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-python": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.2.1.tgz", - "integrity": "sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==", + "node_modules/@astrojs/react/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@codemirror/autocomplete": "^6.3.2", - "@codemirror/language": "^6.8.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.2.1", - "@lezer/python": "^1.1.4" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-rust": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.2.tgz", - "integrity": "sha512-EZaGjCUegtiU7kSMvOfEZpaCReowEf3yNidYu7+vfuGTm9ow4mthAparY5hisJqOHmJowVH3Upu+eJlUji6qqA==", + "node_modules/@astrojs/react/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/rust": "^1.0.0" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-sass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz", - "integrity": "sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==", + "node_modules/@astrojs/react/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@codemirror/lang-css": "^6.2.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.0.2", - "@lezer/sass": "^1.0.0" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-sql": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.10.0.tgz", - "integrity": "sha512-6ayPkEd/yRw0XKBx5uAiToSgGECo/GY2NoJIHXIIQh1EVwLuKoU8BP/qK0qH5NLXAbtJRLuT73hx7P9X34iO4w==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-vue": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz", - "integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@codemirror/lang-html": "^6.0.0", - "@codemirror/lang-javascript": "^6.1.2", - "@codemirror/language": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.3.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-wast": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz", - "integrity": "sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-xml": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz", - "integrity": "sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], "license": "MIT", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.4.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/xml": "^1.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/lang-yaml": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@codemirror/lang-yaml/-/lang-yaml-6.1.3.tgz", - "integrity": "sha512-AZ8DJBuXGVHybpBQhmZtgew5//4hv3tdkXnr3vDmOUMJRuB6vn/uuwtmTOTlqEaQFg3hQSVeA90NmvIQyUV6FQ==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], "license": "MIT", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.2.0", - "@lezer/lr": "^1.0.0", - "@lezer/yaml": "^1.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/language": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.4.tgz", - "integrity": "sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.23.0", - "@lezer/common": "^1.5.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0", - "style-mod": "^4.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@codemirror/language-data": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@codemirror/language-data/-/language-data-6.5.2.tgz", - "integrity": "sha512-CPkWBKrNS8stYbEU5kwBwTf3JB1kghlbh4FSAwzGW2TEscdeHHH4FGysREW86Mqnj3Qn09s0/6Ea/TutmoTobg==", - "license": "MIT", - "dependencies": { - "@codemirror/lang-angular": "^0.1.0", - "@codemirror/lang-cpp": "^6.0.0", - "@codemirror/lang-css": "^6.0.0", - "@codemirror/lang-go": "^6.0.0", - "@codemirror/lang-html": "^6.0.0", - "@codemirror/lang-java": "^6.0.0", - "@codemirror/lang-javascript": "^6.0.0", - "@codemirror/lang-jinja": "^6.0.0", - "@codemirror/lang-json": "^6.0.0", - "@codemirror/lang-less": "^6.0.0", - "@codemirror/lang-liquid": "^6.0.0", - "@codemirror/lang-markdown": "^6.0.0", - "@codemirror/lang-php": "^6.0.0", - "@codemirror/lang-python": "^6.0.0", - "@codemirror/lang-rust": "^6.0.0", - "@codemirror/lang-sass": "^6.0.0", - "@codemirror/lang-sql": "^6.0.0", - "@codemirror/lang-vue": "^0.1.1", - "@codemirror/lang-wast": "^6.0.0", - "@codemirror/lang-xml": "^6.0.0", - "@codemirror/lang-yaml": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/legacy-modes": "^6.4.0" - } - }, - "node_modules/@codemirror/legacy-modes": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.5.3.tgz", - "integrity": "sha512-xCsmIzH78MyWkib9jlPaaun57XNkfbMIhagfaZVd0iLTqlpw3jXaIcbZm72MTmmn64eTZpBVNjbyYh+QXnxRsg==", - "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0" - } - }, - "node_modules/@codemirror/lint": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.7.tgz", - "integrity": "sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==", - "license": "MIT", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.42.0", - "crelt": "^1.0.5" - } - }, - "node_modules/@codemirror/merge": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/@codemirror/merge/-/merge-6.12.2.tgz", - "integrity": "sha512-V8JvyAPjHbPupqP7BeMcsdsYCbyPij74jxIbaIJDORI+VZzW44zFmon8bF+oxGWvOKhcRmkiUMXd8MxHr3YA2w==", - "license": "MIT", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.17.0", - "@lezer/highlight": "^1.0.0", - "style-mod": "^4.1.0" - } - }, - "node_modules/@codemirror/search": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.1.tgz", - "integrity": "sha512-uMe5UO6PamJtSHrXhhHOzSX3ReWtiJrva6GnPMwSOrZtiExb5X5eExhr2OUZQVvdxPsKpY3Ro2mFbQadpPWmHA==", - "license": "MIT", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.37.0", - "crelt": "^1.0.5" - } - }, - "node_modules/@codemirror/state": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.1.tgz", - "integrity": "sha512-9QzNDgE4EYDnAHfrTlR2lwiPciiOymLtwKK+8yHQzCc7GXhAP9xdEbEJFy2IWB1j9UGUl9BsgMmTo/ImA02T7A==", - "license": "MIT", - "dependencies": { - "@marijn/find-cluster-break": "^1.0.0" - } - }, - "node_modules/@codemirror/view": { - "version": "6.43.6", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.6.tgz", - "integrity": "sha512-EVunGSYN1wz1p75WY1s3Xg7t3i8Yol0kGZGizNdX9BUFgMFILYVe8/u6EVpo7Ff5PwbZuILb4QAq7IZoKzIEQA==", - "license": "MIT", - "dependencies": { - "@codemirror/state": "^6.7.0", - "crelt": "^1.0.6", - "style-mod": "^4.1.0", - "w3c-keyname": "^2.2.4" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@ctrl/tinycolor": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", - "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/@emmetio/abbreviation": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", - "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", - "license": "MIT", - "dependencies": { - "@emmetio/scanner": "^1.0.4" - } - }, - "node_modules/@emmetio/css-abbreviation": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", - "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", - "license": "MIT", - "dependencies": { - "@emmetio/scanner": "^1.0.4" - } - }, - "node_modules/@emmetio/css-parser": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@emmetio/css-parser/-/css-parser-0.4.1.tgz", - "integrity": "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==", - "license": "MIT", - "dependencies": { - "@emmetio/stream-reader": "^2.2.0", - "@emmetio/stream-reader-utils": "^0.1.0" - } - }, - "node_modules/@emmetio/html-matcher": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz", - "integrity": "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==", - "license": "ISC", - "dependencies": { - "@emmetio/scanner": "^1.0.0" - } - }, - "node_modules/@emmetio/scanner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", - "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==", - "license": "MIT" - }, - "node_modules/@emmetio/stream-reader": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz", - "integrity": "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==", - "license": "MIT" - }, - "node_modules/@emmetio/stream-reader-utils": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz", - "integrity": "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==", - "license": "MIT" - }, - "node_modules/@emnapi/core": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", - "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], "license": "MIT", "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", - "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "cpu": [ - "ppc64" + "s390x" ], "license": "MIT", "optional": true, "os": [ - "aix" + "linux" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "node_modules/@astrojs/react/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ - "arm" + "x64" ], "license": "MIT", "optional": true, "os": [ - "android" + "linux" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "node_modules/@astrojs/react/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "android" + "netbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "node_modules/@astrojs/react/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "android" + "netbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "node_modules/@astrojs/react/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "darwin" + "openbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "node_modules/@astrojs/react/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "darwin" + "openbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "node_modules/@astrojs/react/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "freebsd" + "openharmony" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "node_modules/@astrojs/react/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" + "sunos" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "node_modules/@astrojs/react/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "node_modules/@astrojs/react/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ "ia32" ], "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "node_modules/@astrojs/react/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ - "loong64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } + "node_modules/@astrojs/react/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "license": "MIT" }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@astrojs/react/node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, "engines": { - "node": ">=18" + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", - "cpu": [ - "riscv64" - ], + "node_modules/@astrojs/react/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", - "cpu": [ - "s390x" - ], + "node_modules/@astrojs/react/node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": ">=0.10.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", - "cpu": [ - "x64" - ], + "node_modules/@astrojs/react/node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, "engines": { - "node": ">=18" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", - "cpu": [ - "arm64" - ], + "node_modules/@astrojs/sitemap": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", + "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "sitemap": "^8.0.2", + "stream-replace-string": "^2.0.0", + "zod": "^3.25.76" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", - "cpu": [ - "x64" - ], + "node_modules/@astrojs/starlight": { + "version": "0.37.6", + "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.37.6.tgz", + "integrity": "sha512-wQrKwH431q+8FsLBnNQeG+R36TMtEGxTQ2AuiVpcx9APcazvL3n7wVW8mMmYyxX0POjTnxlcWPkdMGR3Yj1L+w==", "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@astrojs/markdown-remark": "^6.3.1", + "@astrojs/mdx": "^4.2.3", + "@astrojs/sitemap": "^3.3.0", + "@pagefind/default-ui": "^1.3.0", + "@types/hast": "^3.0.4", + "@types/js-yaml": "^4.0.9", + "@types/mdast": "^4.0.4", + "astro-expressive-code": "^0.41.1", + "bcp-47": "^2.1.0", + "hast-util-from-html": "^2.0.1", + "hast-util-select": "^6.0.2", + "hast-util-to-string": "^3.0.0", + "hastscript": "^9.0.0", + "i18next": "^23.11.5", + "js-yaml": "^4.1.0", + "klona": "^2.0.6", + "magic-string": "^0.30.17", + "mdast-util-directive": "^3.0.0", + "mdast-util-to-markdown": "^2.1.0", + "mdast-util-to-string": "^4.0.0", + "pagefind": "^1.3.0", + "rehype": "^13.0.1", + "rehype-format": "^5.0.0", + "remark-directive": "^3.0.0", + "ultrahtml": "^1.6.0", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.2" + }, + "peerDependencies": { + "astro": "^5.5.0" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", - "cpu": [ - "arm64" - ], + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, "engines": { - "node": ">=18" + "node": "18.20.8 || ^20.3.0 || >=22.0.0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } + "node_modules/@astrojs/underscore-redirects": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-1.0.0.tgz", + "integrity": "sha512-qZxHwVnmb5FXuvRsaIGaqWgnftjCuMY+GSbaVZdBmE4j8AfgPqKPxYp8SUERyJcjpKCEmO4wD6ybuGH8A2kVRQ==", + "license": "MIT" }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", - "cpu": [ - "arm64" - ], + "node_modules/@astrojs/yaml2ts": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.4.tgz", + "integrity": "sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==", "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "dependencies": { + "yaml": "^2.8.3" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=18" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@expressive-code/core": { - "version": "0.41.7", - "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.41.7.tgz", - "integrity": "sha512-ck92uZYZ9Wba2zxkiZLsZGi9N54pMSAVdrI9uW3Oo9AtLglD5RmrdTwbYPCT2S/jC36JGB2i+pnQtBm/Ib2+dg==", + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "license": "MIT", "dependencies": { - "@ctrl/tinycolor": "^4.0.4", - "hast-util-select": "^6.0.2", - "hast-util-to-html": "^9.0.1", - "hast-util-to-text": "^4.0.1", - "hastscript": "^9.0.0", - "postcss": "^8.4.38", - "postcss-nested": "^6.0.1", - "unist-util-visit": "^5.0.0", - "unist-util-visit-parents": "^6.0.1" + "@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" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@expressive-code/plugin-frames": { - "version": "0.41.7", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.41.7.tgz", - "integrity": "sha512-diKtxjQw/979cTglRFaMCY/sR6hWF0kSMg8jsKLXaZBSfGS0I/Hoe7Qds3vVEgeoW+GHHQzMcwvgx/MOIXhrTA==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "license": "MIT", "dependencies": { - "@expressive-code/core": "^0.41.7" + "@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" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@expressive-code/plugin-shiki": { - "version": "0.41.7", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.41.7.tgz", - "integrity": "sha512-DL605bLrUOgqTdZ0Ot5MlTaWzppRkzzqzeGEu7ODnHF39IkEBbFdsC7pbl3LbUQ1DFtnfx6rD54k/cdofbW6KQ==", - "license": "MIT", + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", "dependencies": { - "@expressive-code/core": "^0.41.7", - "shiki": "^3.2.2" + "yallist": "^3.0.2" } }, - "node_modules/@expressive-code/plugin-text-markers": { - "version": "0.41.7", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.41.7.tgz", - "integrity": "sha512-Ewpwuc5t6eFdZmWlFyeuy3e1PTQC0jFvw2Q+2bpcWXbOZhPLsT7+h8lsSIJxb5mS7wZko7cKyQ2RLYDyK6Fpmw==", - "license": "MIT", - "dependencies": { - "@expressive-code/core": "^0.41.7" + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@floating-ui/core": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", - "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "license": "MIT", - "dependencies": { - "@floating-ui/utils": "^0.2.12" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@floating-ui/dom": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", - "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.8.0", - "@floating-ui/utils": "^0.2.12" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@floating-ui/react": { - "version": "0.27.20", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.20.tgz", - "integrity": "sha512-CMqMy7OaXl9W0eq1Uy7L7i2Y/anPvHmFmESd2CEw0t5YvZhcVCeo4MBevAmswRllX7Y2dEidA4ozGPunLSTQpw==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "license": "MIT", "dependencies": { - "@floating-ui/react-dom": "^2.1.9", - "@floating-ui/utils": "^0.2.12", - "tabbable": "^6.0.0" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=17.0.0", - "react-dom": ">=17.0.0" + "@babel/core": "^7.0.0" } }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", - "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.8.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@floating-ui/utils": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", - "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", - "license": "MIT" + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@github/copilot": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.39.tgz", - "integrity": "sha512-AY0VPYf6QQm88wUcOav2B36iedWKBUaMegKRxxY2uIHESiU6HueEuQR/n7D3U2UdD0zLox3jFRjYbZAsr2CgkQ==", - "license": "SEE LICENSE IN LICENSE.md", - "bin": { - "copilot": "npm-loader.js" - }, - "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.39", - "@github/copilot-darwin-x64": "1.0.39", - "@github/copilot-linux-arm64": "1.0.39", - "@github/copilot-linux-x64": "1.0.39", - "@github/copilot-win32-arm64": "1.0.39", - "@github/copilot-win32-x64": "1.0.39" + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.39.tgz", - "integrity": "sha512-E8WfNL43NMzMTDDpCiYikaEmYCMAr6mz8LHrJtkaFuVXVkBr/q2NI3hAtwHFy8M11Fac/MeIe3/VEymWwwh3kw==", - "cpu": [ - "arm64" - ], - "license": "SEE LICENSE IN LICENSE.md", - "optional": true, - "os": [ - "darwin" - ], - "bin": { - "copilot-darwin-arm64": "copilot" + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.39.tgz", - "integrity": "sha512-0zbC4lDVX7l8Wvq+JSCMjO0xTN69nWLejTBCl3Ev5bP6P+/7wPURcUvZKoHEaXxOULQ3AGj0DwZNAsvvQkA/6Q==", - "cpu": [ - "x64" - ], - "license": "SEE LICENSE IN LICENSE.md", - "optional": true, - "os": [ - "darwin" - ], - "bin": { - "copilot-darwin-x64": "copilot" + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@github/copilot-language-server": { - "version": "1.480.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server/-/copilot-language-server-1.480.0.tgz", - "integrity": "sha512-VrhbHluNTygFpPW8G8g0wl+hWT9iGRbdnAzmmIjPo0ph0SQGs5mth0g6jE/b8NDqw+SLsVabFDBhrTvJu+wQvA==", + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "license": "MIT", "dependencies": { - "vscode-languageserver-protocol": "^3.17.5" + "@babel/types": "^7.29.8" }, "bin": { - "copilot-language-server": "dist/language-server.js" + "parser": "bin/babel-parser.js" }, - "optionalDependencies": { - "@github/copilot-language-server-darwin-arm64": "1.480.0", - "@github/copilot-language-server-darwin-x64": "1.480.0", - "@github/copilot-language-server-linux-arm64": "1.480.0", - "@github/copilot-language-server-linux-x64": "1.480.0", - "@github/copilot-language-server-win32-arm64": "1.480.0", - "@github/copilot-language-server-win32-x64": "1.480.0" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@github/copilot-language-server-darwin-arm64": { - "version": "1.480.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server-darwin-arm64/-/copilot-language-server-darwin-arm64-1.480.0.tgz", - "integrity": "sha512-MPgNMfigh0phF843YiTvt6Fr8Dla27RFPxjyEUkd9KSBmz/LMcvhKMGESOIfn/ExebNFXEgbQ+O/nZ8kCjQCFQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@github/copilot-language-server-darwin-x64": { - "version": "1.480.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server-darwin-x64/-/copilot-language-server-darwin-x64-1.480.0.tgz", - "integrity": "sha512-icV2UrpB6DwONHTFdmoGTWUx4kTrSG6CHb++4lk6jiheMj2rbG1T/Lbb4KkvLtlBBn1p8B+9J0axW0hD78aA8g==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@github/copilot-language-server-linux-arm64": { - "version": "1.480.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server-linux-arm64/-/copilot-language-server-linux-arm64-1.480.0.tgz", - "integrity": "sha512-PpLtqeOQvvfSkpfn61+1fowEieihzuevFVunTmYMqihRHgR4iAxoKVpebjxjVG1KWxhDjqijaRC/2TORiKfaHg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@github/copilot-language-server-linux-x64": { - "version": "1.480.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server-linux-x64/-/copilot-language-server-linux-x64-1.480.0.tgz", - "integrity": "sha512-9LJr5RPHWrE7isMQWPcu57QaKOUzycKeQN4vCMbryAIKj8Vv/a1ujKopfNnTEwZCnvIO7WhWoQUzjdbAB8Gnig==", - "cpu": [ - "x64" - ], + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@github/copilot-language-server-win32-arm64": { - "version": "1.480.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server-win32-arm64/-/copilot-language-server-win32-arm64-1.480.0.tgz", - "integrity": "sha512-Z+h/8vDG/bHV0tETMZxOUO84cNrcU0IalPS1JLIgWsAXKgI6g2GWd3ljClVuT0HshgAA1lpve+AnHeIxcm+3yw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@github/copilot-language-server-win32-x64": { - "version": "1.480.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server-win32-x64/-/copilot-language-server-win32-x64-1.480.0.tgz", - "integrity": "sha512-zIyzU9ozZFMusza+rZrBYExuO8bc4+OGcR5wvisTdo/YtfzzjS+82UeEOJE18KUsRdJ1poHJplEez+3h09+uWg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.39.tgz", - "integrity": "sha512-x88FuByweJlHlAmUZXjq4JlmtqgoM57Fe7nXzQkGr2Y5wnc2EDydBzFYEOlYDSWozQreimaJIm0KEMAA5T8/Fg==", - "cpu": [ - "arm64" - ], - "license": "SEE LICENSE IN LICENSE.md", - "optional": true, - "os": [ - "linux" - ], - "bin": { - "copilot-linux-arm64": "copilot" + "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" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@github/copilot-linux-x64": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.39.tgz", - "integrity": "sha512-ssahg8r7a0VCsHVXPRmFFXx70xNAxaTM2SZfG7qPRfFB2OM8gHrW26F2oikTklDF6D+A2MfSAMpzJLBUZbPnhw==", - "cpu": [ - "x64" - ], - "license": "SEE LICENSE IN LICENSE.md", - "optional": true, - "os": [ - "linux" - ], - "bin": { - "copilot-linux-x64": "copilot" + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@github/copilot-sdk": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@github/copilot-sdk/-/copilot-sdk-0.3.0.tgz", - "integrity": "sha512-SUo35k56pzzgYgwmDPHcu7kZxPrzXbH66IWXaEf6pmb94DlA709F82HrrDeja087TL4djJ9OuvRFWWOKCosAsg==", + "node_modules/@capsizecss/unpack": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.1.tgz", + "integrity": "sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.36-0", - "vscode-jsonrpc": "^8.2.1", - "zod": "^4.3.6" + "fontkitten": "^1.0.3" }, "engines": { - "node": ">=20.0.0" + "node": ">=18" } }, - "node_modules/@github/copilot-sdk/node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.2.tgz", + "integrity": "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==", + "license": "MIT OR Apache-2.0", + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.39.tgz", - "integrity": "sha512-hhBWGZQIywbp6MBxlqMX2GSmHqtUAOGwpo9b0igscecL4i0kz89QNasC+mKiN+zFEHP6I8gggOu87XPI17Io8Q==", - "cpu": [ - "arm64" - ], - "license": "SEE LICENSE IN LICENSE.md", - "optional": true, - "os": [ - "win32" - ], - "bin": { - "copilot-win32-arm64": "copilot.exe" + "node_modules/@cloudflare/unenv-preset": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz", + "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==", + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": ">1.20260305.0 <2.0.0-0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } } }, - "node_modules/@github/copilot-win32-x64": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.39.tgz", - "integrity": "sha512-0ehlMtBiwKjmfEY3hVZggdn7qrmPMC8ueBQv/b+6UY3SMRS/M/1Y7xkOCwG84NvJsktdSsk3SlQnE2LbkTVpSA==", + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20260825.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260825.1.tgz", + "integrity": "sha512-oHu38dwaUuzAilyTb0QkQ1YxU/kzqzIQybCvQKAhiK1CGtQS9h0MmjIZYogv3g8cFGGY2k+Wxs0wV9hHK8z78g==", "cpu": [ "x64" ], - "license": "SEE LICENSE IN LICENSE.md", + "license": "Apache-2.0", "optional": true, "os": [ - "win32" + "darwin" ], - "bin": { - "copilot-win32-x64": "copilot.exe" - } - }, - "node_modules/@graphql-typed-document-node/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "license": "MIT", - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", - "license": "MIT", - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "hono": "^4" - } - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "license": "MIT", "engines": { - "node": ">=18" + "node": ">=16" } }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20260825.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260825.1.tgz", + "integrity": "sha512-ak5zh8YGEjxQQ78bVo7gzU+tcg2fSFxMIjOPZtWk56a/rIYLbGu6ECcliqnYfMUlragg68H0JuVpfdr3BR5Alw==", "cpu": [ "arm64" ], @@ -2573,3765 +2463,939 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" + "node": ">=16" } }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20260825.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260825.1.tgz", + "integrity": "sha512-bNQvzz6NemWAwixDRz1fQa5T+E5lS4xpB7A/H/72ULxrjVpHmq8CGFPSbdmRp3dvgBjZTgp7wHdGLISLSVd9Gg==", "cpu": [ "x64" ], "license": "Apache-2.0", "optional": true, "os": [ - "darwin" + "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" + "node": ">=16" } }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20260825.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260825.1.tgz", + "integrity": "sha512-a5E61YsnNCHHQMnmYsbVXInzeYqFqAMwm/wo16dWW4klXDr6T1bm7u1h5G7ZkxVM7+rtc69oe0yVHjDEqzpYVg==", "cpu": [ "arm64" ], - "license": "LGPL-3.0-or-later", + "license": "Apache-2.0", "optional": true, "os": [ - "darwin" + "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=16" } }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20260825.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260825.1.tgz", + "integrity": "sha512-EokzVY2suzRSzeURi2HpHnySR5mo6aF5V1klFIqFOZp2YJyXXTI8AvQgYzhlmGTZY3LNL41jjkUQunOM2OErgQ==", "cpu": [ "x64" ], - "license": "LGPL-3.0-or-later", + "license": "Apache-2.0", "optional": true, "os": [ - "darwin" + "win32" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=16" } }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@codemirror/autocomplete": { + "version": "6.20.3", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.3.tgz", + "integrity": "sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" } }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@codemirror/commands": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.11.0.tgz", + "integrity": "sha512-/K4Rl5BN0OtTiPWmJCdqODu38XnDMsDxKY5rgrPnCkutPTJf2wVbkoixLfealF5Kwse/s8P8M5jAiURiwSwnFA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.7.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" } }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@codemirror/lang-angular": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@codemirror/lang-angular/-/lang-angular-0.1.4.tgz", + "integrity": "sha512-oap+gsltb/fzdlTQWD6BFF4bSLKcDnlxDsLdePiJpCVNKWXSTAbiiQeYI3UmES+BLAdkmIC1WjyztC1pi/bX4g==", + "license": "MIT", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-javascript": "^6.1.2", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.3" } }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" + "node_modules/@codemirror/lang-cpp": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.3.tgz", + "integrity": "sha512-URM26M3vunFFn9/sm6rzqrBzDgfWuDixp85uTY49wKudToc2jTHUrKIGGKs+QWND+YLofNNZpxcNGRynFJfvgA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/cpp": "^1.0.0" } }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@lexical/clipboard": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.35.0.tgz", - "integrity": "sha512-ko7xSIIiayvDiqjNDX6fgH9RlcM6r9vrrvJYTcfGVBor5httx16lhIi0QJZ4+RNPvGtTjyFv4bwRmsixRRwImg==", - "license": "MIT", - "dependencies": { - "@lexical/html": "0.35.0", - "@lexical/list": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/code": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/code/-/code-0.35.0.tgz", - "integrity": "sha512-ox4DZwETQ9IA7+DS6PN8RJNwSAF7RMjL7YTVODIqFZ5tUFIf+5xoCHbz7Fll0Bvixlp12hVH90xnLwTLRGpkKw==", - "license": "MIT", - "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0", - "prismjs": "^1.30.0" - } - }, - "node_modules/@lexical/devtools-core": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.35.0.tgz", - "integrity": "sha512-C2wwtsMCR6ZTfO0TqpSM17RLJWyfHmifAfCTjFtOJu15p3M6NO/nHYK5Mt7YMQteuS89mOjB4ng8iwoLEZ6QpQ==", - "license": "MIT", - "dependencies": { - "@lexical/html": "0.35.0", - "@lexical/link": "0.35.0", - "@lexical/mark": "0.35.0", - "@lexical/table": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - }, - "peerDependencies": { - "react": ">=17.x", - "react-dom": ">=17.x" - } - }, - "node_modules/@lexical/dragon": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.35.0.tgz", - "integrity": "sha512-SL6mT5pcqrt6hEbJ16vWxip5+r3uvMd0bQV5UUxuk+cxIeuP86iTgRh0HFR7SM2dRTYovL6/tM/O+8QLAUGTIg==", - "license": "MIT", - "dependencies": { - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/hashtag": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.35.0.tgz", - "integrity": "sha512-LYJWzXuO2ZjKsvQwrLkNZiS2TsjwYkKjlDgtugzejquTBQ/o/nfSn/MmVx6EkYLOYizaJemmZbz3IBh+u732FA==", - "license": "MIT", - "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/history": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.35.0.tgz", - "integrity": "sha512-onjDRLLxGbCfHexSxxrQaDaieIHyV28zCDrbxR5dxTfW8F8PxjuNyuaG0z6o468AXYECmclxkP+P4aT6poHEpQ==", - "license": "MIT", - "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/html": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.35.0.tgz", - "integrity": "sha512-rXGFE5S5rKsg3tVnr1s4iEgOfCApNXGpIFI3T2jGEShaCZ5HLaBY9NVBXnE9Nb49e9bkDkpZ8FZd1qokCbQXbw==", - "license": "MIT", - "dependencies": { - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/link": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.35.0.tgz", - "integrity": "sha512-+0Wx6cBwO8TfdMzpkYFacsmgFh8X1rkiYbq3xoLvk3qV8upYxaMzK1s8Q1cpKmWyI0aZrU6z7fiK4vUqB7+69w==", - "license": "MIT", - "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/list": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.35.0.tgz", - "integrity": "sha512-owsmc8iwgExBX8sFe8fKTiwJVhYULt9hD1RZ/HwfaiEtRZZkINijqReOBnW2mJfRxBzhFSWc4NG3ISB+fHYzqw==", - "license": "MIT", - "dependencies": { - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/mark": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.35.0.tgz", - "integrity": "sha512-W0hwMTAVeexvpk9/+J6n1G/sNkpI/Meq1yeDazahFLLAwXLHtvhIAq2P/klgFknDy1hr8X7rcsQuN/bqKcKHYg==", - "license": "MIT", - "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/markdown": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.35.0.tgz", - "integrity": "sha512-BlNyXZAt4gWidMw0SRWrhBETY1BpPglFBZI7yzfqukFqgXRh7HUQA28OYeI/nsx9pgNob8TiUduUwShqqvOdEA==", - "license": "MIT", - "dependencies": { - "@lexical/code": "0.35.0", - "@lexical/link": "0.35.0", - "@lexical/list": "0.35.0", - "@lexical/rich-text": "0.35.0", - "@lexical/text": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/offset": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/offset/-/offset-0.35.0.tgz", - "integrity": "sha512-DRE4Df6qYf2XiV6foh6KpGNmGAv2ANqt3oVXpyS6W8hTx3+cUuAA1APhCZmLNuU107um4zmHym7taCu6uXW5Yg==", - "license": "MIT", - "dependencies": { - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/overflow": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.35.0.tgz", - "integrity": "sha512-B25YvnJQTGlZcrNv7b0PJBLWq3tl8sql497OHfYYLem7EOMPKKDGJScJAKM/91D4H/mMAsx5gnA/XgKobriuTg==", - "license": "MIT", - "dependencies": { - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/plain-text": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.35.0.tgz", - "integrity": "sha512-lwBCUNMJf7Gujp2syVWMpKRahfbTv5Wq+H3HK1Q1gKH1P2IytPRxssCHvexw9iGwprSyghkKBlbF3fGpEdIJvQ==", - "license": "MIT", - "dependencies": { - "@lexical/clipboard": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/react": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/react/-/react-0.35.0.tgz", - "integrity": "sha512-uYAZSqumH8tRymMef+A0f2hQvMwplKK9DXamcefnk3vSNDHHqRWQXpiUo6kD+rKWuQmMbVa5RW4xRQebXEW+1A==", - "license": "MIT", - "dependencies": { - "@floating-ui/react": "^0.27.8", - "@lexical/devtools-core": "0.35.0", - "@lexical/dragon": "0.35.0", - "@lexical/hashtag": "0.35.0", - "@lexical/history": "0.35.0", - "@lexical/link": "0.35.0", - "@lexical/list": "0.35.0", - "@lexical/mark": "0.35.0", - "@lexical/markdown": "0.35.0", - "@lexical/overflow": "0.35.0", - "@lexical/plain-text": "0.35.0", - "@lexical/rich-text": "0.35.0", - "@lexical/table": "0.35.0", - "@lexical/text": "0.35.0", - "@lexical/utils": "0.35.0", - "@lexical/yjs": "0.35.0", - "lexical": "0.35.0", - "react-error-boundary": "^3.1.4" - }, - "peerDependencies": { - "react": ">=17.x", - "react-dom": ">=17.x" - } - }, - "node_modules/@lexical/rich-text": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.35.0.tgz", - "integrity": "sha512-qEHu8g7vOEzz9GUz1VIUxZBndZRJPh9iJUFI+qTDHj+tQqnd5LCs+G9yz6jgNfiuWWpezTp0i1Vz/udNEuDPKQ==", - "license": "MIT", - "dependencies": { - "@lexical/clipboard": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/selection": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.35.0.tgz", - "integrity": "sha512-mMtDE7Q0nycXdFTTH/+ta6EBrBwxBB4Tg8QwsGntzQ1Cq//d838dpXpFjJOqHEeVHUqXpiuj+cBG8+bvz/rPRw==", - "license": "MIT", - "dependencies": { - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/table": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.35.0.tgz", - "integrity": "sha512-9jlTlkVideBKwsEnEkqkdg7A3mije1SvmfiqoYnkl1kKJCLA5iH90ywx327PU0p+bdnURAytWUeZPXaEuEl2OA==", - "license": "MIT", - "dependencies": { - "@lexical/clipboard": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/text": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/text/-/text-0.35.0.tgz", - "integrity": "sha512-uaMh46BkysV8hK8wQwp5g/ByZW+2hPDt8ahAErxtf8NuzQem1FHG/f5RTchmFqqUDVHO3qLNTv4AehEGmXv8MA==", - "license": "MIT", - "dependencies": { - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/utils": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.35.0.tgz", - "integrity": "sha512-2H393EYDnFznYCDFOW3MHiRzwEO5M/UBhtUjvTT+9kc+qhX4U3zc8ixQalo5UmZ5B2nh7L/inXdTFzvSRXtsRA==", - "license": "MIT", - "dependencies": { - "@lexical/list": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/table": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/yjs": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.35.0.tgz", - "integrity": "sha512-3DSP7QpmTGYU9bN/yljP0PIao4tNIQtsR4ycauWNSawxs/GQCZtSmAPcLRnCm6qpqsDDjUtKjO/1Ej8FRp0m0w==", - "license": "MIT", - "dependencies": { - "@lexical/offset": "0.35.0", - "@lexical/selection": "0.35.0", - "lexical": "0.35.0" - }, - "peerDependencies": { - "yjs": ">=13.5.22" - } - }, - "node_modules/@lezer/common": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz", - "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", - "license": "MIT" - }, - "node_modules/@lezer/cpp": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.6.tgz", - "integrity": "sha512-vh9gWWJOXFVY8HBHK3Twzq8MgwG2iN4GSyzBP9sCGTe37P15x2R14VaBQk0VA0ezTRN1KHYBBsHhvpGZ2Xy/pA==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/css": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.3.4.tgz", - "integrity": "sha512-N+tn9tej2hPvyKgHEApMOQfHczDJCwxrRFS3SPn9QjYN+uwHvEDnCgKRrb3mxDYxRS8sKMM8fhC3+lc04Abz5Q==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.3.0" - } - }, - "node_modules/@lezer/go": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@lezer/go/-/go-1.0.1.tgz", - "integrity": "sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.3.0" - } - }, - "node_modules/@lezer/highlight": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz", - "integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.3.0" - } - }, - "node_modules/@lezer/html": { - "version": "1.3.13", - "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.13.tgz", - "integrity": "sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/java": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.3.tgz", - "integrity": "sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/javascript": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.4.tgz", - "integrity": "sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.1.3", - "@lezer/lr": "^1.3.0" - } - }, - "node_modules/@lezer/json": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", - "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/lr": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz", - "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@lezer/markdown": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.7.1.tgz", - "integrity": "sha512-MEBZeFSBxgteUjEC3Wxg2Dwld5/JxRKG267L3bMFdibm8KjqSdiJYBeFw1Nt1CM8+zKMpSIEHblY8FD9z38sJQ==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.5.0", - "@lezer/highlight": "^1.0.0" - } - }, - "node_modules/@lezer/php": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.5.tgz", - "integrity": "sha512-W7asp9DhM6q0W6DYNwIkLSKOvxlXRrif+UXBMxzsJUuqmhE7oVU+gS3THO4S/Puh7Xzgm858UNaFi6dxTP8dJA==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.1.0" - } - }, - "node_modules/@lezer/python": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.19.tgz", - "integrity": "sha512-MhQIURHRytsNzP/YXnqpYKW6la6voAH3kyplTOOiCdjyFY6cWWGFVmYVdHIPrElqSDf4iCDktQCockB9FxuhzQ==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/rust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.2.tgz", - "integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/sass": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@lezer/sass/-/sass-1.1.0.tgz", - "integrity": "sha512-3mMGdCTUZ/84ArHOuXWQr37pnf7f+Nw9ycPUeKX+wu19b7pSMcZGLbaXwvD2APMBDOGxPmpK/O6S1v1EvLoqgQ==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/xml": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.6.tgz", - "integrity": "sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/yaml": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@lezer/yaml/-/yaml-1.0.4.tgz", - "integrity": "sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw==", - "license": "MIT", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.4.0" - } - }, - "node_modules/@marijn/find-cluster-break": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.3.tgz", - "integrity": "sha512-FY+MKLBoTsLNJF/eLWaOsXGdz6uh3Iu1axjPf6TUq92IYumcTcXWHoS747JARLkcdlJ/Waiaxc5wQfFO8jC6NA==", - "license": "MIT" - }, - "node_modules/@mdx-js/mdx": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", - "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "acorn": "^8.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-scope": "^1.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "recma-build-jsx": "^1.0.0", - "recma-jsx": "^1.0.0", - "recma-stringify": "^1.0.0", - "rehype-recma": "^1.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/@mdx-js/mdx/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "node_modules/@mdxeditor/editor": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@mdxeditor/editor/-/editor-4.0.4.tgz", - "integrity": "sha512-fUUWoIFfHB4g+PHkcpKp5zRfoMmDWrVeSaoB4x81759J2xrWsmYYoCYx0oVLcL6HXat8f/8LprlRmAxpcIPnLQ==", - "license": "MIT", - "dependencies": { - "@codemirror/commands": "^6.2.4", - "@codemirror/lang-markdown": "^6.2.3", - "@codemirror/language-data": "^6.5.1", - "@codemirror/merge": "^6.4.0", - "@codemirror/state": "^6.4.0", - "@codemirror/view": "^6.23.0", - "@lexical/clipboard": "^0.35.0", - "@lexical/link": "^0.35.0", - "@lexical/list": "^0.35.0", - "@lexical/markdown": "^0.35.0", - "@lexical/plain-text": "^0.35.0", - "@lexical/react": "^0.35.0", - "@lexical/rich-text": "^0.35.0", - "@lexical/selection": "^0.35.0", - "@lexical/utils": "^0.35.0", - "@mdxeditor/gurx": "^1.2.4", - "@radix-ui/colors": "^3.0.0", - "@radix-ui/react-dialog": "^1.1.11", - "@radix-ui/react-icons": "^1.3.2", - "@radix-ui/react-popover": "^1.1.11", - "@radix-ui/react-popper": "^1.2.4", - "@radix-ui/react-select": "^2.2.2", - "@radix-ui/react-toggle-group": "^1.1.7", - "@radix-ui/react-toolbar": "^1.1.7", - "@radix-ui/react-tooltip": "^1.2.4", - "classnames": "^2.3.2", - "cm6-theme-basic-light": "^0.2.0", - "codemirror": "^6.0.1", - "downshift": "^7.6.0", - "js-yaml": "4.2.0", - "lexical": "^0.35.0", - "mdast-util-directive": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-frontmatter": "^2.0.1", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-highlight-mark": "^1.2.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-to-markdown": "^2.1.0", - "micromark-extension-directive": "^3.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.1", - "micromark-extension-highlight-mark": "^1.2.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs": "^3.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.1", - "micromark-util-symbol": "^2.0.0", - "react-hook-form": "^7.56.1", - "unidiff": "^1.0.2" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "react": ">= 18 || >= 19", - "react-dom": ">= 18 || >= 19" - } - }, - "node_modules/@mdxeditor/gurx": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@mdxeditor/gurx/-/gurx-1.2.4.tgz", - "integrity": "sha512-9ZykIFYhKaXaaSPCs1cuI+FvYDegJjbKwmA4ASE/zY+hJY6EYqvoye4esiO85CjhOw9aoD/izD/CU78/egVqmg==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "react": ">= 18 || >= 19", - "react-dom": ">= 18 || >= 19" - } - }, - "node_modules/@mediabunny/aac-encoder": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/@mediabunny/aac-encoder/-/aac-encoder-1.45.0.tgz", - "integrity": "sha512-vLQw8cY7Me6pvTTMkMhOiH9UCuINzfTOETCeDxbGNeNfDqc/7QlxloUH1Ylp/Zz2ek0O8kc6YdygV2vWAPakrA==", - "license": "MPL-2.0", - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/Vanilagy" - }, - "peerDependencies": { - "mediabunny": "^1.0.0" - } - }, - "node_modules/@mediabunny/flac-encoder": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/@mediabunny/flac-encoder/-/flac-encoder-1.45.0.tgz", - "integrity": "sha512-LfKbAMZVkxRS7PpEIVnWOY/l0KcHv+rjO7pYY3O0TPCZvbHWfrnQjn8JPacPIfuq6Yv7r4f8lhcl7yHSynoRkQ==", - "license": "MPL-2.0", - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/Vanilagy" - }, - "peerDependencies": { - "mediabunny": "^1.0.0" - } - }, - "node_modules/@mediabunny/mp3-encoder": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/@mediabunny/mp3-encoder/-/mp3-encoder-1.45.0.tgz", - "integrity": "sha512-Bobi6AaQYEc7TWmPJ8Q0/hcUtBN7pLUC2qjoC7oZR4FcGqGztby6k7A1SWlmswoMOEIhYsOrgDaemrSDAC0QVQ==", - "license": "MPL-2.0", - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/Vanilagy" - }, - "peerDependencies": { - "mediabunny": "^1.0.0" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", - "integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==", - "license": "MIT", - "dependencies": { - "@hono/node-server": "^1.19.9", - "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" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@cfworker/json-schema": "^4.1.1", - "zod": "^3.25 || ^4.0" - }, - "peerDependenciesMeta": { - "@cfworker/json-schema": { - "optional": true - }, - "zod": { - "optional": false - } - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@module-federation/error-codes": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz", - "integrity": "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==", - "license": "MIT" - }, - "node_modules/@module-federation/runtime": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz", - "integrity": "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==", - "license": "MIT", - "dependencies": { - "@module-federation/error-codes": "0.22.0", - "@module-federation/runtime-core": "0.22.0", - "@module-federation/sdk": "0.22.0" - } - }, - "node_modules/@module-federation/runtime-core": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz", - "integrity": "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==", - "license": "MIT", - "dependencies": { - "@module-federation/error-codes": "0.22.0", - "@module-federation/sdk": "0.22.0" - } - }, - "node_modules/@module-federation/runtime-tools": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz", - "integrity": "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==", - "license": "MIT", - "dependencies": { - "@module-federation/runtime": "0.22.0", - "@module-federation/webpack-bundler-runtime": "0.22.0" - } - }, - "node_modules/@module-federation/sdk": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz", - "integrity": "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==", - "license": "MIT" - }, - "node_modules/@module-federation/webpack-bundler-runtime": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz", - "integrity": "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==", - "license": "MIT", - "dependencies": { - "@module-federation/runtime": "0.22.0", - "@module-federation/sdk": "0.22.0" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", - "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.5.0", - "@emnapi/runtime": "^1.5.0", - "@tybys/wasm-util": "^0.10.1" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@octokit/app": { - "version": "16.1.2", - "resolved": "https://registry.npmjs.org/@octokit/app/-/app-16.1.2.tgz", - "integrity": "sha512-8j7sEpUYVj18dxvh0KWj6W/l6uAiVRBl1JBDVRqH1VHKAO/G5eRVl4yEoYACjakWers1DjUkcCHyJNQK47JqyQ==", - "license": "MIT", - "dependencies": { - "@octokit/auth-app": "^8.1.2", - "@octokit/auth-unauthenticated": "^7.0.3", - "@octokit/core": "^7.0.6", - "@octokit/oauth-app": "^8.0.3", - "@octokit/plugin-paginate-rest": "^14.0.0", - "@octokit/types": "^16.0.0", - "@octokit/webhooks": "^14.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/auth-app": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-8.2.0.tgz", - "integrity": "sha512-vVjdtQQwomrZ4V46B9LaCsxsySxGoHsyw6IYBov/TqJVROrlYdyNgw5q6tQbB7KZt53v1l1W53RiqTvpzL907g==", - "license": "MIT", - "dependencies": { - "@octokit/auth-oauth-app": "^9.0.3", - "@octokit/auth-oauth-user": "^6.0.2", - "@octokit/request": "^10.0.6", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "toad-cache": "^3.7.0", - "universal-github-app-jwt": "^2.2.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/auth-oauth-app": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-9.0.3.tgz", - "integrity": "sha512-+yoFQquaF8OxJSxTb7rnytBIC2ZLbLqA/yb71I4ZXT9+Slw4TziV9j/kyGhUFRRTF2+7WlnIWsePZCWHs+OGjg==", - "license": "MIT", - "dependencies": { - "@octokit/auth-oauth-device": "^8.0.3", - "@octokit/auth-oauth-user": "^6.0.2", - "@octokit/request": "^10.0.6", - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/auth-oauth-device": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-8.0.3.tgz", - "integrity": "sha512-zh2W0mKKMh/VWZhSqlaCzY7qFyrgd9oTWmTmHaXnHNeQRCZr/CXy2jCgHo4e4dJVTiuxP5dLa0YM5p5QVhJHbw==", - "license": "MIT", - "dependencies": { - "@octokit/oauth-methods": "^6.0.2", - "@octokit/request": "^10.0.6", - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/auth-oauth-user": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-6.0.2.tgz", - "integrity": "sha512-qLoPPc6E6GJoz3XeDG/pnDhJpTkODTGG4kY0/Py154i/I003O9NazkrwJwRuzgCalhzyIeWQ+6MDvkUmKXjg/A==", - "license": "MIT", - "dependencies": { - "@octokit/auth-oauth-device": "^8.0.3", - "@octokit/oauth-methods": "^6.0.2", - "@octokit/request": "^10.0.6", - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/auth-token": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", - "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", - "license": "MIT", - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/auth-unauthenticated": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-7.0.3.tgz", - "integrity": "sha512-8Jb1mtUdmBHL7lGmop9mU9ArMRUTRhg8vp0T1VtZ4yd9vEm3zcLwmjQkhNEduKawOOORie61xhtYIhTDN+ZQ3g==", - "license": "MIT", - "dependencies": { - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/core": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", - "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", - "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^6.0.0", - "@octokit/graphql": "^9.0.3", - "@octokit/request": "^10.0.6", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "before-after-hook": "^4.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/endpoint": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", - "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/graphql": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", - "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", - "license": "MIT", - "dependencies": { - "@octokit/request": "^10.0.6", - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/oauth-app": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-8.0.3.tgz", - "integrity": "sha512-jnAjvTsPepyUaMu9e69hYBuozEPgYqP4Z3UnpmvoIzHDpf8EXDGvTY1l1jK0RsZ194oRd+k6Hm13oRU8EoDFwg==", - "license": "MIT", - "dependencies": { - "@octokit/auth-oauth-app": "^9.0.2", - "@octokit/auth-oauth-user": "^6.0.1", - "@octokit/auth-unauthenticated": "^7.0.2", - "@octokit/core": "^7.0.5", - "@octokit/oauth-authorization-url": "^8.0.0", - "@octokit/oauth-methods": "^6.0.1", - "@types/aws-lambda": "^8.10.83", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/oauth-authorization-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-8.0.0.tgz", - "integrity": "sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==", - "license": "MIT", - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/oauth-methods": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-6.0.2.tgz", - "integrity": "sha512-HiNOO3MqLxlt5Da5bZbLV8Zarnphi4y9XehrbaFMkcoJ+FL7sMxH/UlUsCVxpddVu4qvNDrBdaTVE2o4ITK8ng==", - "license": "MIT", - "dependencies": { - "@octokit/oauth-authorization-url": "^8.0.0", - "@octokit/request": "^10.0.6", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", - "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", - "license": "MIT" - }, - "node_modules/@octokit/openapi-webhooks-types": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-webhooks-types/-/openapi-webhooks-types-12.1.0.tgz", - "integrity": "sha512-WiuzhOsiOvb7W3Pvmhf8d2C6qaLHXrWiLBP4nJ/4kydu+wpagV5Fkz9RfQwV2afYzv3PB+3xYgp4mAdNGjDprA==", - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-graphql": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-6.0.0.tgz", - "integrity": "sha512-crfpnIoFiBtRkvPqOyLOsw12XsveYuY2ieP6uYDosoUegBJpSVxGwut9sxUgFFcll3VTOTqpUf8yGd8x1OmAkQ==", - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", - "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", - "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/plugin-retry": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.1.0.tgz", - "integrity": "sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw==", - "license": "MIT", - "dependencies": { - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "bottleneck": "^2.15.3" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=7" - } - }, - "node_modules/@octokit/plugin-throttling": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.3.tgz", - "integrity": "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0", - "bottleneck": "^2.15.3" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": "^7.0.0" - } - }, - "node_modules/@octokit/request": { - "version": "10.0.11", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.11.tgz", - "integrity": "sha512-+s7HUxjfFqOMS9VlIwDffq0MikjSAK0gSpG73W+meAvVAvX4MBrHYTK5Bj3Uot55qFT4gzUtfzE4mGWY4Br8/Q==", - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^11.0.3", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "content-type": "^2.0.0", - "json-with-bigint": "^3.5.3", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/request-error": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", - "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/types": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", - "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^27.0.0" - } - }, - "node_modules/@octokit/webhooks": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-14.2.0.tgz", - "integrity": "sha512-da6KbdNCV5sr1/txD896V+6W0iamFWrvVl8cHkBSPT+YlvmT3DwXa4jxZnQc+gnuTEqSWbBeoSZYTayXH9wXcw==", - "license": "MIT", - "dependencies": { - "@octokit/openapi-webhooks-types": "12.1.0", - "@octokit/request-error": "^7.0.0", - "@octokit/webhooks-methods": "^6.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/webhooks-methods": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-6.0.0.tgz", - "integrity": "sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ==", - "license": "MIT", - "engines": { - "node": ">= 20" - } - }, - "node_modules/@oslojs/encoding": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", - "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", - "license": "MIT" - }, - "node_modules/@oxc-project/types": { - "version": "0.139.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", - "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@pagefind/darwin-arm64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.5.2.tgz", - "integrity": "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/darwin-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.5.2.tgz", - "integrity": "sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/default-ui": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.5.2.tgz", - "integrity": "sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==", - "license": "MIT" - }, - "node_modules/@pagefind/freebsd-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.5.2.tgz", - "integrity": "sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@pagefind/linux-arm64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.5.2.tgz", - "integrity": "sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/linux-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.5.2.tgz", - "integrity": "sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/windows-arm64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/windows-arm64/-/windows-arm64-1.5.2.tgz", - "integrity": "sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@pagefind/windows-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.5.2.tgz", - "integrity": "sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@poppinss/colors": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", - "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", - "license": "MIT", - "dependencies": { - "kleur": "^4.1.5" - } - }, - "node_modules/@poppinss/dumper": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", - "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", - "license": "MIT", - "dependencies": { - "@poppinss/colors": "^4.1.5", - "@sindresorhus/is": "^7.0.2", - "supports-color": "^10.0.0" - } - }, - "node_modules/@poppinss/dumper/node_modules/supports-color": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", - "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/@poppinss/exception": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", - "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", - "license": "MIT" - }, - "node_modules/@radix-ui/colors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz", - "integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==", - "license": "MIT" - }, - "node_modules/@radix-ui/number": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.2.tgz", - "integrity": "sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig==", - "license": "MIT" - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.5.tgz", - "integrity": "sha512-d86WIWFYNtGA0H/d8exstrTRTp7eWJYlYJbtNofxr/3ljupZYn6EFDG/Qgu/0Kc8v7yMUxySagqJsL1+PdYjWg==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.11.tgz", - "integrity": "sha512-Kdil9BB1rIFC/khmf4hC35bn8701AJcizTU7G7cUbEbk5XqqbjDuHW60uUfKqO5WojjZcbAW51Q7P0hRmMLw8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.7" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.12.tgz", - "integrity": "sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-slot": "1.3.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz", - "integrity": "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.0.tgz", - "integrity": "sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.19.tgz", - "integrity": "sha512-+HhbN2+YtkRgVirjZ2afMeutQRuGOrdkWR5+EFC58SJojGmtyNQwYzgi6tHBpOxvFHefMtPeHdgtjz0BOGxFQg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-dismissable-layer": "1.1.15", - "@radix-ui/react-focus-guards": "1.1.4", - "@radix-ui/react-focus-scope": "1.1.12", - "@radix-ui/react-id": "1.1.2", - "@radix-ui/react-portal": "1.1.13", - "@radix-ui/react-presence": "1.1.7", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-slot": "1.3.0", - "@radix-ui/react-use-controllable-state": "1.2.3", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.7.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz", - "integrity": "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.15.tgz", - "integrity": "sha512-b0XaRlzn2QKuo10XyNgi2DAJDf5XC9d1nD3FJcuvCjbR7+4Ad28zmZsLsqx+hvDEzMnRuZaZxZm9gYObV6RmRA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-use-callback-ref": "1.1.2", - "@radix-ui/react-use-effect-event": "0.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.4.tgz", - "integrity": "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.12.tgz", - "integrity": "sha512-jjk/lqTeNL0azUx5ZYzVrl4NgaDIrdzTNE4mABV9yBFI7FQqN7pIgzV1bTleUezP2QiTGA1BFTqY8MegDgWX9A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-use-callback-ref": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-icons": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz", - "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==", - "license": "MIT", - "peerDependencies": { - "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz", - "integrity": "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.19.tgz", - "integrity": "sha512-jkrTdQVxnIB8fpn0NyyxW9CTB5aCXZZelVz5z+Xmii6g5WxMqS3fInNslZ63puP39+Puu4jYohUK31y3dT87gQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-dismissable-layer": "1.1.15", - "@radix-ui/react-focus-guards": "1.1.4", - "@radix-ui/react-focus-scope": "1.1.12", - "@radix-ui/react-id": "1.1.2", - "@radix-ui/react-popper": "1.3.3", - "@radix-ui/react-portal": "1.1.13", - "@radix-ui/react-presence": "1.1.7", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-slot": "1.3.0", - "@radix-ui/react-use-controllable-state": "1.2.3", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.7.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popper": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.3.tgz", - "integrity": "sha512-mS7dGpyjv6b+gsDjLF7e0ia1W4Im1B1hSCy2yuXlHuvnZxHKagfDaobt/KAKt27EpZMit2pss8eJBVyVjEWM+g==", - "license": "MIT", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.11", - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-use-callback-ref": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.2", - "@radix-ui/react-use-rect": "1.1.2", - "@radix-ui/react-use-size": "1.1.2", - "@radix-ui/rect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.13.tgz", - "integrity": "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-use-layout-effect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.7.tgz", - "integrity": "sha512-zBZ4QM5XG3JRanDmqXYf3MD6th4AFXFmgU6KNMFzUaV6F3uw9I5/zjMUvFriSEn5ewo1nxuibvyxJdmLlDcslA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.7.tgz", - "integrity": "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.3.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.15.tgz", - "integrity": "sha512-40svmmugfM3mUN7VUDGVE1tQGOhyi8enlGD0CNJEcMM36C1f71PKM21DFgNHUfem0XnA+d8H8oN3Z9ZpJjSslg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-collection": "1.1.12", - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-direction": "1.1.2", - "@radix-ui/react-id": "1.1.2", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-use-callback-ref": "1.1.2", - "@radix-ui/react-use-controllable-state": "1.2.3", - "@radix-ui/react-use-is-hydrated": "0.1.1", - "@radix-ui/react-use-layout-effect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.3.3.tgz", - "integrity": "sha512-L5RQTXz6Anxsf9CCv+pTgiAsUpyVj7rJxsGtmhFaEOJ++cVfXucv4qWfsIO0AIB4NAhi3yovWGVMKKS1Xf1Wrg==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.2", - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-collection": "1.1.12", - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-direction": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.15", - "@radix-ui/react-focus-guards": "1.1.4", - "@radix-ui/react-focus-scope": "1.1.12", - "@radix-ui/react-id": "1.1.2", - "@radix-ui/react-popper": "1.3.3", - "@radix-ui/react-portal": "1.1.13", - "@radix-ui/react-presence": "1.1.7", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-slot": "1.3.0", - "@radix-ui/react-use-callback-ref": "1.1.2", - "@radix-ui/react-use-controllable-state": "1.2.3", - "@radix-ui/react-use-layout-effect": "1.1.2", - "@radix-ui/react-use-previous": "1.1.2", - "@radix-ui/react-visually-hidden": "1.2.7", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.7.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-separator": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.11.tgz", - "integrity": "sha512-jRhe86+8PF7VZ1u14eOWVOuh2BuAhALg/FT1VcMC4OHedMTRUazDnDlKTt+yxo5cRNKHMfmvZ4sSQtWDeMV4CQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.7" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.0.tgz", - "integrity": "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.3" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.14.tgz", - "integrity": "sha512-QI/hB65XKWACA66P64A+aHxtLUgHJeJLkaQa+awUNXT6T3swndtY5DojeHA+vldrTspMTtFBd7HfZ9QGbM1Qrw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-use-controllable-state": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.15.tgz", - "integrity": "sha512-gIC5Q+Xljg7lmUdzSuDoy0t97yZn1sZl00Ra37ZvKrYdWnQLU6sWLd09yG8cIB9jUAlQfHgJ2ACAG00MFwsqSQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-direction": "1.1.2", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-roving-focus": "1.1.15", - "@radix-ui/react-toggle": "1.1.14", - "@radix-ui/react-use-controllable-state": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toolbar": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.1.15.tgz", - "integrity": "sha512-t/iEuVjUnXXtrsGK40AA43uIx37sn3AqZ7oAVnPICK6lFJP6dzMzWR3U9b6eCfFjb6wtSEqkJ9Rn9xDjiOx20g==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-direction": "1.1.2", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-roving-focus": "1.1.15", - "@radix-ui/react-separator": "1.1.11", - "@radix-ui/react-toggle-group": "1.1.15" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.12.tgz", - "integrity": "sha512-U3HoftgWnmla78vzQbLvKKb7bUYJxoiiqYFzp1wu/TBMyDqMZSuCl3aRICsD6EfVEwcJD2mumGDGUXLFVqQHKA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.5", - "@radix-ui/react-compose-refs": "1.1.3", - "@radix-ui/react-context": "1.2.0", - "@radix-ui/react-dismissable-layer": "1.1.15", - "@radix-ui/react-id": "1.1.2", - "@radix-ui/react-popper": "1.3.3", - "@radix-ui/react-portal": "1.1.13", - "@radix-ui/react-presence": "1.1.7", - "@radix-ui/react-primitive": "2.1.7", - "@radix-ui/react-slot": "1.3.0", - "@radix-ui/react-use-controllable-state": "1.2.3", - "@radix-ui/react-visually-hidden": "1.2.7" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz", - "integrity": "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.3.tgz", - "integrity": "sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.3", - "@radix-ui/react-use-layout-effect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-effect-event": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz", - "integrity": "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-is-hydrated": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.1.tgz", - "integrity": "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz", - "integrity": "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-previous": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.2.tgz", - "integrity": "sha512-IGBQPtRFdhN6MQ8dbegVmBq1LVZluya3F1jWY+puIcQC3MHctRwTDSBWCkL/3ZcnMJLTMJ++Z+ktmvg0F89iCw==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.2.tgz", - "integrity": "sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==", - "license": "MIT", - "dependencies": { - "@radix-ui/rect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.2.tgz", - "integrity": "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.7.tgz", - "integrity": "sha512-1wNZBggTDK3GRuuQ6nP4k2yi7a6l7I5qbMPbZcRsrGsGVead/f/d5FhEzUvqFs0bcrDLx7n1zKQ3JvLR6whaaw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.7" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/rect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.2.tgz", - "integrity": "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==", - "license": "MIT" - }, - "node_modules/@react-email/render": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@react-email/render/-/render-2.1.0.tgz", - "integrity": "sha512-F+zE3O6d6sW6Aj2UjvZAA17R7tJKM7kcq2mgV6k4HCT8jeLLFaVP2txMtH1lgqYFRMZ0Gxsd37q2PRyiXLXXxA==", - "license": "MIT", - "dependencies": { - "entities": "^4.5.0", - "html-to-text": "^9.0.5", - "html5parser": "^3.0.0", - "prettier": "^3.5.3" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": "^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" - } - }, - "node_modules/@reduxjs/toolkit": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", - "integrity": "sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@standard-schema/spec": "^1.0.0", - "@standard-schema/utils": "^0.3.0", - "immer": "^11.0.0", - "redux": "^5.0.1", - "redux-thunk": "^3.1.0", - "reselect": "^5.1.0" - }, - "peerDependencies": { - "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", - "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-redux": { - "optional": true - } + "node_modules/@codemirror/lang-css": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", + "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.1.7" } }, - "node_modules/@remotion/bundler": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/bundler/-/bundler-4.0.477.tgz", - "integrity": "sha512-nbTCxUtiNWg06zbIJ9ia0v8UrK/o486sE/KKvMqs6u+FCdQDO86cOEmqSoGsImsDe3TwHWTUws9V7kpcXA+E8g==", - "license": "SEE LICENSE IN LICENSE.md", + "node_modules/@codemirror/lang-go": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-go/-/lang-go-6.0.1.tgz", + "integrity": "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==", + "license": "MIT", "dependencies": { - "@remotion/media-parser": "4.0.477", - "@remotion/studio": "4.0.477", - "@remotion/studio-shared": "4.0.477", - "@remotion/timeline-utils": "4.0.477", - "@rspack/core": "1.7.11", - "@rspack/plugin-react-refresh": "1.6.1", - "css-loader": "7.1.4", - "esbuild": "0.28.1", - "react-refresh": "0.18.0", - "remotion": "4.0.477", - "style-loader": "4.0.0", - "webpack": "5.105.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/go": "^1.0.0" } }, - "node_modules/@remotion/canvas-capture": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/canvas-capture/-/canvas-capture-4.0.477.tgz", - "integrity": "sha512-/4M9rP/ltAggYXqhAMHj6wxBX7zt1CdekK8JEY7bbIi2uFHltD2qRTfT8B7DZaOjG+b6cWZ/VROusfiuvpMCNg==", - "license": "Remotion License", + "node_modules/@codemirror/lang-html": { + "version": "6.4.12", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.12.tgz", + "integrity": "sha512-pw2ReWKUqSkbvh76RAT4NYxiogRu+PWkR2ukAwO9uOgrm8uipkzjtKKtNpyeAQwHOqxEeSvAXZ6vr3AfyB9y/w==", + "license": "MIT", "dependencies": { - "mediabunny": "1.45.0", - "remotion": "4.0.477" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.12" } }, - "node_modules/@remotion/compositor-darwin-arm64": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/compositor-darwin-arm64/-/compositor-darwin-arm64-4.0.477.tgz", - "integrity": "sha512-d6PfHTTnlkqqY+C+40m3hgDzkevG/wONd2ZsWJEShx1QRN3UHgTuhW1xKZw/E+DpTGXdvCVmeM2QCsBrpSfnKQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@remotion/compositor-darwin-x64": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/compositor-darwin-x64/-/compositor-darwin-x64-4.0.477.tgz", - "integrity": "sha512-tnuSFZGV9Vg/9N8YjvATPfOJKD31GM+B9XFuVLdcHc7+hyikdX46xa8pKKKUVLOkeJegs8A22Wi+V1/AEnWqEQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@remotion/compositor-linux-arm64-gnu": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-arm64-gnu/-/compositor-linux-arm64-gnu-4.0.477.tgz", - "integrity": "sha512-3xhtIdqufAiO49v8tbbkPDyDkd7uRRB8vx+vSPi9+THUI/h0uqi+ylENHtsWj7veEDCiTB3Y4ZjsmotEVMHQJA==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@remotion/compositor-linux-arm64-musl": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-arm64-musl/-/compositor-linux-arm64-musl-4.0.477.tgz", - "integrity": "sha512-qenbQpmSm9XQn2uaW3yt+P5YBgQuCb+jitTfQunhR1l0tk6oC2kKPn14qKu9jAs7vZPH11bV8V76DcYUhqdbAQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@remotion/compositor-linux-x64-gnu": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-x64-gnu/-/compositor-linux-x64-gnu-4.0.477.tgz", - "integrity": "sha512-P+5MRPkaRskoUgseJxEko53KvW/Rzu0Ow/htyzJjC9XpigtjYTJPKRKOjw4/ihPYJoVDH+e9s/jyOF06odzLVA==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@remotion/compositor-linux-x64-musl": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-x64-musl/-/compositor-linux-x64-musl-4.0.477.tgz", - "integrity": "sha512-uas9/X85QfI6p5vTOCcjqmCBizIK6QeZlIXVrKc1fcmSzhk3udjbzx9XDDo71m6Bz8IfWeqV1ZkX/5pLJYufFg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@remotion/compositor-win32-x64-msvc": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/compositor-win32-x64-msvc/-/compositor-win32-x64-msvc-4.0.477.tgz", - "integrity": "sha512-7oldAftiUrFDI1U5z0zN87xfhpuJuIrLrNP16GFgj0JZN4AzRQT/iGYoH5+H2/clT910mlq4YtrfAv1RsHe4Cg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@remotion/licensing": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/licensing/-/licensing-4.0.477.tgz", - "integrity": "sha512-Ayor3/+CyXkyYUvzxEFcTVWe46+ld1i9jyrmZY9OqO77gCQ3khOAivjNsI/4foFgnfb7aRNvcCBYr1D9iZLn/w==", - "license": "MIT" - }, - "node_modules/@remotion/media-parser": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/media-parser/-/media-parser-4.0.477.tgz", - "integrity": "sha512-E6qAQvY2s5VzvGNi0FOiDjcEm2RWRsRO+5012ZQneAUqp54JVP/6M3oXM5i34wo9PLjMSqfXgmxLPRdF08YokQ==", - "license": "Remotion License https://remotion.dev/license" - }, - "node_modules/@remotion/media-utils": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/media-utils/-/media-utils-4.0.477.tgz", - "integrity": "sha512-ItEniXSb0OUnZJSjcOxoD6HvHoQ1wbn0FQNz/BkuVo7AQLvVeY1GGf9XWIa0mvqRRd790jYhW9QOqToeJryeeQ==", + "node_modules/@codemirror/lang-java": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.2.tgz", + "integrity": "sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ==", "license": "MIT", "dependencies": { - "mediabunny": "1.45.0", - "remotion": "4.0.477" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@codemirror/language": "^6.0.0", + "@lezer/java": "^1.0.0" } }, - "node_modules/@remotion/player": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/player/-/player-4.0.477.tgz", - "integrity": "sha512-x0aWSsbXQIlW2V5R6hVksHsyw4CBWN0ctbc0b8Aq5kbAg901vZmDXMekNXyMicqPyzwPRfTeDfpPyGq5RwvOSA==", - "license": "SEE LICENSE IN LICENSE.md", + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.5.tgz", + "integrity": "sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==", + "license": "MIT", "dependencies": { - "remotion": "4.0.477" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" } }, - "node_modules/@remotion/renderer": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/renderer/-/renderer-4.0.477.tgz", - "integrity": "sha512-OKHhmjLZwvXAOKvby7WCpyHGFUGUFMofKjJMGobx/yeyG0k/So/FSFBJQBBpP8XSdHY1RmFqKpMiKIO5SACB5A==", - "license": "SEE LICENSE IN LICENSE.md", + "node_modules/@codemirror/lang-jinja": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-jinja/-/lang-jinja-6.0.1.tgz", + "integrity": "sha512-P5kyHLObzjtbGj16h+hyvZTxJhSjBEeSx4wMjbnAf3b0uwTy2+F0zGjMZL4PQOm/mh2eGZ5xUDVZXgwP783Nsw==", + "license": "MIT", "dependencies": { - "@remotion/licensing": "4.0.477", - "@remotion/streaming": "4.0.477", - "execa": "5.1.1", - "remotion": "4.0.477", - "source-map": "0.8.0-beta.0", - "ws": "8.20.1" - }, - "optionalDependencies": { - "@remotion/compositor-darwin-arm64": "4.0.477", - "@remotion/compositor-darwin-x64": "4.0.477", - "@remotion/compositor-linux-arm64-gnu": "4.0.477", - "@remotion/compositor-linux-arm64-musl": "4.0.477", - "@remotion/compositor-linux-x64-gnu": "4.0.477", - "@remotion/compositor-linux-x64-musl": "4.0.477", - "@remotion/compositor-win32-x64-msvc": "4.0.477" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.2.0", + "@lezer/lr": "^1.4.0" } }, - "node_modules/@remotion/streaming": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/streaming/-/streaming-4.0.477.tgz", - "integrity": "sha512-GXSR5BaC2UaaPHwAEBbuwXXDedrUfa3KQ1GpwDBKfr/F2rm0QxOPgPoVzB14lt7CvaQsuig22NZD6h6BTDAH5A==", - "license": "MIT" + "node_modules/@codemirror/lang-json": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz", + "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } }, - "node_modules/@remotion/studio": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/studio/-/studio-4.0.477.tgz", - "integrity": "sha512-/Z+yYf1g6dQAQbGqthulE+Ra9PBNqAcgRYb3F6mu3iFf9zfZimP3BIZ03eYrXDDC1SeyVt9LaZu4QcXZv/VkOg==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.31", - "@remotion/canvas-capture": "4.0.477", - "@remotion/media-utils": "4.0.477", - "@remotion/player": "4.0.477", - "@remotion/renderer": "4.0.477", - "@remotion/studio-shared": "4.0.477", - "@remotion/timeline-utils": "4.0.477", - "@remotion/web-renderer": "4.0.477", - "@remotion/zod-types": "4.0.477", - "mediabunny": "1.45.0", - "memfs": "3.4.3", - "open": "8.4.2", - "remotion": "4.0.477", - "semver": "7.5.3", - "zod": "4.3.6" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "node_modules/@codemirror/lang-less": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-less/-/lang-less-6.0.2.tgz", + "integrity": "sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==", + "license": "MIT", + "dependencies": { + "@codemirror/lang-css": "^6.2.0", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@remotion/studio-shared": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/studio-shared/-/studio-shared-4.0.477.tgz", - "integrity": "sha512-uZqv9tTBddFbMgAuLr0huCu7f8A8LIlq1r+6Ap5tnRlbj1olmNVGWpA2jkChY8jJZADMIED8klhS4amV5nKiZQ==", + "node_modules/@codemirror/lang-liquid": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-liquid/-/lang-liquid-6.3.2.tgz", + "integrity": "sha512-6PDVU3ZnfeYyz1at1E/ttorErZvZFXXt1OPhtfe1EZJ2V2iDFa0CwPqPgG5F7NXN0yONGoBogKmFAafKTqlwIw==", "license": "MIT", "dependencies": { - "remotion": "4.0.477" + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.1" } }, - "node_modules/@remotion/studio/node_modules/@remotion/zod-types": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/zod-types/-/zod-types-4.0.477.tgz", - "integrity": "sha512-3gglLjiN6AJo1ayqbxZCBhpLJIieD3XGUnBgJ7b1Ew+C881wjOSH8O5vt+pvrO1E0RizjqbbBkbV99FwLFrC/A==", + "node_modules/@codemirror/lang-markdown": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.5.2.tgz", + "integrity": "sha512-AwBOdkWYuA//WcM0xO5PfHPUcmz/O2i5o0Nsg1U69SII/loCJlFI1Romd9xp2HYb1kYJRGZotyqRghuHH5n8Kw==", "license": "MIT", "dependencies": { - "remotion": "4.0.477" - }, - "peerDependencies": { - "zod": "4.3.6" + "@codemirror/autocomplete": "^6.7.1", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/markdown": "^1.0.0" } }, - "node_modules/@remotion/studio/node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "node_modules/@codemirror/lang-php": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.2.tgz", + "integrity": "sha512-ZKy2v1n8Fc8oEXj0Th0PUMXzQJ0AIR6TaZU+PbDHExFwdu+guzOA4jmCHS1Nz4vbFezwD7LyBdDnddSJeScMCA==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/php": "^1.0.0" } }, - "node_modules/@remotion/timeline-utils": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/timeline-utils/-/timeline-utils-4.0.477.tgz", - "integrity": "sha512-OsOjNPCNwp08z0KG6OlcQD0UCsAuyIRD4xG+BIXvKaYvsyUiX0+KmsGD7ULANcd/uj6oj3xldNp0yqOi0v6IYA==", + "node_modules/@codemirror/lang-python": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.2.1.tgz", + "integrity": "sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==", "license": "MIT", "dependencies": { - "mediabunny": "1.45.0" + "@codemirror/autocomplete": "^6.3.2", + "@codemirror/language": "^6.8.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/python": "^1.1.4" } }, - "node_modules/@remotion/web-renderer": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/@remotion/web-renderer/-/web-renderer-4.0.477.tgz", - "integrity": "sha512-w8xkoDNg14DbfQXGvx5XfgaPu38dHzX1BFG2lUgMKoB7RfVoXMbU/VHEQ3Xm+vYGxW2Pa3oRgCWqUVprikR4+g==", - "license": "UNLICENSED", + "node_modules/@codemirror/lang-rust": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.2.tgz", + "integrity": "sha512-EZaGjCUegtiU7kSMvOfEZpaCReowEf3yNidYu7+vfuGTm9ow4mthAparY5hisJqOHmJowVH3Upu+eJlUji6qqA==", + "license": "MIT", "dependencies": { - "@mediabunny/aac-encoder": "1.45.0", - "@mediabunny/flac-encoder": "1.45.0", - "@mediabunny/mp3-encoder": "1.45.0", - "@remotion/licensing": "4.0.477", - "mediabunny": "1.45.0", - "remotion": "4.0.477" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" + "@codemirror/language": "^6.0.0", + "@lezer/rust": "^1.0.0" } }, - "node_modules/@repomix/strip-comments": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@repomix/strip-comments/-/strip-comments-2.4.2.tgz", - "integrity": "sha512-7a18ODb043eszMBr6mpVWz802xIRMzdmptarVxTtnMIW7ZQzba/v8jLp3kcHUHb76uRkyJRPpGSwdm7+8GmsEA==", + "node_modules/@codemirror/lang-sass": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz", + "integrity": "sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==", "license": "MIT", - "engines": { - "node": ">=10" + "dependencies": { + "@codemirror/lang-css": "^6.2.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/sass": "^1.0.0" } }, - "node_modules/@repomix/tree-sitter-wasms": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@repomix/tree-sitter-wasms/-/tree-sitter-wasms-0.1.17.tgz", - "integrity": "sha512-tc3HnFqdMF1pXhIMzG3aTaBDpIiHK2tPfn3fwqA6P3WTbHa+1EuuTubbKshvmN7xCHP5Ojz0/VW4R+XvR88KOw==", - "license": "Unlicense" + "node_modules/@codemirror/lang-sql": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.10.0.tgz", + "integrity": "sha512-6ayPkEd/yRw0XKBx5uAiToSgGECo/GY2NoJIHXIIQh1EVwLuKoU8BP/qK0qH5NLXAbtJRLuT73hx7P9X34iO4w==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", - "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", - "cpu": [ - "arm64" - ], + "node_modules/@codemirror/lang-vue": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz", + "integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-javascript": "^6.1.2", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.1" } }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", - "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", - "cpu": [ - "arm64" - ], + "node_modules/@codemirror/lang-wast": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz", + "integrity": "sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", - "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", - "cpu": [ - "x64" - ], + "node_modules/@codemirror/lang-xml": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz", + "integrity": "sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/xml": "^1.0.0" } }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", - "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", - "cpu": [ - "x64" - ], + "node_modules/@codemirror/lang-yaml": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-yaml/-/lang-yaml-6.1.3.tgz", + "integrity": "sha512-AZ8DJBuXGVHybpBQhmZtgew5//4hv3tdkXnr3vDmOUMJRuB6vn/uuwtmTOTlqEaQFg3hQSVeA90NmvIQyUV6FQ==", "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.2.0", + "@lezer/lr": "^1.0.0", + "@lezer/yaml": "^1.0.0" } }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", - "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", - "cpu": [ - "arm" - ], + "node_modules/@codemirror/language": { + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.4.tgz", + "integrity": "sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.5.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" } }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", - "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], + "node_modules/@codemirror/language-data": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/language-data/-/language-data-6.5.2.tgz", + "integrity": "sha512-CPkWBKrNS8stYbEU5kwBwTf3JB1kghlbh4FSAwzGW2TEscdeHHH4FGysREW86Mqnj3Qn09s0/6Ea/TutmoTobg==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/lang-angular": "^0.1.0", + "@codemirror/lang-cpp": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-go": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-java": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/lang-jinja": "^6.0.0", + "@codemirror/lang-json": "^6.0.0", + "@codemirror/lang-less": "^6.0.0", + "@codemirror/lang-liquid": "^6.0.0", + "@codemirror/lang-markdown": "^6.0.0", + "@codemirror/lang-php": "^6.0.0", + "@codemirror/lang-python": "^6.0.0", + "@codemirror/lang-rust": "^6.0.0", + "@codemirror/lang-sass": "^6.0.0", + "@codemirror/lang-sql": "^6.0.0", + "@codemirror/lang-vue": "^0.1.1", + "@codemirror/lang-wast": "^6.0.0", + "@codemirror/lang-xml": "^6.0.0", + "@codemirror/lang-yaml": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/legacy-modes": "^6.4.0" } }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", - "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], + "node_modules/@codemirror/legacy-modes": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.5.3.tgz", + "integrity": "sha512-xCsmIzH78MyWkib9jlPaaun57XNkfbMIhagfaZVd0iLTqlpw3jXaIcbZm72MTmmn64eTZpBVNjbyYh+QXnxRsg==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/language": "^6.0.0" } }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", - "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], + "node_modules/@codemirror/lint": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.7.tgz", + "integrity": "sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.42.0", + "crelt": "^1.0.5" } }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", - "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], + "node_modules/@codemirror/merge": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/@codemirror/merge/-/merge-6.12.2.tgz", + "integrity": "sha512-V8JvyAPjHbPupqP7BeMcsdsYCbyPij74jxIbaIJDORI+VZzW44zFmon8bF+oxGWvOKhcRmkiUMXd8MxHr3YA2w==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/highlight": "^1.0.0", + "style-mod": "^4.1.0" } }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", - "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], + "node_modules/@codemirror/search": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.1.tgz", + "integrity": "sha512-uMe5UO6PamJtSHrXhhHOzSX3ReWtiJrva6GnPMwSOrZtiExb5X5eExhr2OUZQVvdxPsKpY3Ro2mFbQadpPWmHA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.37.0", + "crelt": "^1.0.5" } }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", - "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], + "node_modules/@codemirror/state": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.1.tgz", + "integrity": "sha512-9QzNDgE4EYDnAHfrTlR2lwiPciiOymLtwKK+8yHQzCc7GXhAP9xdEbEJFy2IWB1j9UGUl9BsgMmTo/ImA02T7A==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" } }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", - "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", - "cpu": [ - "arm64" - ], + "node_modules/@codemirror/view": { + "version": "6.43.9", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.9.tgz", + "integrity": "sha512-sTuUzTpPMFebRhg6dawChoKKgndIwfjmJgKVxBefPElcU2NwQ6AFroupk0SFqEerQyZOGRfDNnSN8Dw/lMAsXw==", "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@codemirror/state": "^6.7.0", + "crelt": "^1.0.6", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" } }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", - "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", - "cpu": [ - "wasm32" - ], + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/core": "1.11.1", - "@emnapi/runtime": "1.11.1", - "@napi-rs/wasm-runtime": "^1.1.6" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=12" } }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", - "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", - "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "node_modules/@ctrl/tinycolor": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", + "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "engines": { + "node": ">=14" } }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", - "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "node_modules/@emmetio/abbreviation": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", + "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", "license": "MIT", - "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.3" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "@emmetio/scanner": "^1.0.4" } }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", - "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", - "cpu": [ - "arm64" - ], + "node_modules/@emmetio/css-abbreviation": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", + "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@emmetio/scanner": "^1.0.4" } }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", - "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", - "cpu": [ - "x64" - ], + "node_modules/@emmetio/css-parser": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@emmetio/css-parser/-/css-parser-0.4.1.tgz", + "integrity": "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "@emmetio/stream-reader": "^2.2.0", + "@emmetio/stream-reader-utils": "^0.1.0" } }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", - "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", - "license": "MIT" - }, - "node_modules/@rollup/pluginutils": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", - "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==", - "license": "MIT", + "node_modules/@emmetio/html-matcher": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz", + "integrity": "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==", + "license": "ISC", "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "@emmetio/scanner": "^1.0.0" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", - "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "node_modules/@emmetio/scanner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", + "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==", + "license": "MIT" }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", - "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "node_modules/@emmetio/stream-reader": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz", + "integrity": "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==", + "license": "MIT" }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", - "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@emmetio/stream-reader-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz", + "integrity": "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==", + "license": "MIT" }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", - "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", - "cpu": [ - "x64" - ], + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", "license": "MIT", "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "tslib": "^2.4.0" + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", - "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ - "arm64" + "ppc64" ], "license": "MIT", "optional": true, "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", - "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", - "cpu": [ - "x64" + "aix" ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", - "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", - "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", - "cpu": [ - "arm" - ], - "libc": [ - "musl" + "android" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", - "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", - "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" + "android" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", - "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ - "loong64" - ], - "libc": [ - "glibc" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", - "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", - "cpu": [ - "loong64" - ], - "libc": [ - "musl" + "android" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", - "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", - "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ - "ppc64" - ], - "libc": [ - "musl" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", - "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "freebsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", - "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ - "riscv64" - ], - "libc": [ - "musl" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "freebsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", - "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ - "s390x" - ], - "libc": [ - "glibc" + "arm" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", - "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ - "x64" - ], - "libc": [ - "glibc" + "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", - "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ - "x64" - ], - "libc": [ - "musl" + "ia32" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", - "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ - "x64" + "loong64" ], "license": "MIT", "optional": true, "os": [ - "openbsd" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", - "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ - "arm64" + "mips64el" ], "license": "MIT", "optional": true, "os": [ - "openharmony" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", - "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ - "arm64" + "ppc64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", - "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ - "ia32" + "riscv64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", - "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ - "x64" + "s390x" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", - "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.7.11.tgz", - "integrity": "sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q==", - "license": "MIT", - "optionalDependencies": { - "@rspack/binding-darwin-arm64": "1.7.11", - "@rspack/binding-darwin-x64": "1.7.11", - "@rspack/binding-linux-arm64-gnu": "1.7.11", - "@rspack/binding-linux-arm64-musl": "1.7.11", - "@rspack/binding-linux-x64-gnu": "1.7.11", - "@rspack/binding-linux-x64-musl": "1.7.11", - "@rspack/binding-wasm32-wasi": "1.7.11", - "@rspack/binding-win32-arm64-msvc": "1.7.11", - "@rspack/binding-win32-ia32-msvc": "1.7.11", - "@rspack/binding-win32-x64-msvc": "1.7.11" - } - }, - "node_modules/@rspack/binding-darwin-arm64": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.7.11.tgz", - "integrity": "sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "darwin" - ] + "netbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding-darwin-x64": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.7.11.tgz", - "integrity": "sha512-a1+TtTE9ap6RalgFi7FGIgkJP6O4Vy6ctv+9WGJy53E4kuqHR0RygzaiVxCI/GMc/vBT9vY23hyrpWb3d1vtXA==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "darwin" - ] - }, - "node_modules/@rspack/binding-linux-arm64-gnu": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.7.11.tgz", - "integrity": "sha512-P0QrGRPbTWu6RKWfN0bDtbnEps3rXH0MWIMreZABoUrVmNQKtXR6e73J3ub6a+di5s2+K0M2LJ9Bh2/H4UsDUA==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" + "netbsd" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding-linux-arm64-musl": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.7.11.tgz", - "integrity": "sha512-6ky7R43VMjWwmx3Yx7Jl7faLBBMAgMDt+/bN35RgwjiPgsIByz65EwytUVuW9rikB43BGHvA/eqlnjLrUzNBqw==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding-linux-x64-gnu": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.7.11.tgz", - "integrity": "sha512-cuOJMfCOvb2Wgsry5enXJ3iT1FGUjdPqtGUBVupQlEG4ntSYsQ2PtF4wIDVasR3wdxC5nQbipOrDiN/u6fYsdQ==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding-linux-x64-musl": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.7.11.tgz", - "integrity": "sha512-CoK37hva4AmHGh3VCsQXmGr40L36m1/AdnN5LEjUX6kx5rEH7/1nEBN6Ii72pejqDVvk9anEROmPDiPw10tpFg==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ - "x64" - ], - "libc": [ - "musl" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openharmony" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding-wasm32-wasi": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.7.11.tgz", - "integrity": "sha512-OtrmnPUVJMxjNa3eDMfHyPdtlLRmmp/aIm0fQHlAOATbZvlGm12q7rhPW5BXTu1yh+1rQ1/uqvz+SzKEZXuJaQ==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ - "wasm32" + "x64" ], "license": "MIT", "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "1.0.7" + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@rspack/binding-win32-arm64-msvc": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.7.11.tgz", - "integrity": "sha512-lObFW6e5lCWNgTBNwT//yiEDbsxm9QG4BYUojqeXxothuzJ/L6ibXz6+gLMvbOvLGV3nKgkXmx8GvT9WDKR0mA==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -6339,12 +3403,15 @@ "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding-win32-ia32-msvc": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.7.11.tgz", - "integrity": "sha512-0pYGnZd8PPqNR68zQ8skamqNAXEA1sUfXuAdYcknIIRq2wsbiwFzIc0Pov1cIfHYab37G7sSIPBiOUdOWF5Ivw==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -6352,12 +3419,15 @@ "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rspack/binding-win32-x64-msvc": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.7.11.tgz", - "integrity": "sha512-EeQXayoQk/uBkI3pdoXfQBXNIUrADq56L3s/DFyM2pJeUDrWmhfIw2UFIGkYPTMSCo8F2JcdcGM32FGJrSnU0Q==", + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -6365,1568 +3435,1494 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rspack/core": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.7.11.tgz", - "integrity": "sha512-rsD9b+Khmot5DwCMiB3cqTQo53ioPG3M/A7BySu8+0+RS7GCxKm+Z+mtsjtG/vsu4Tn2tcqCdZtA3pgLoJB+ew==", - "license": "MIT", - "dependencies": { - "@module-federation/runtime-tools": "0.22.0", - "@rspack/binding": "1.7.11", - "@rspack/lite-tapable": "1.1.0" - }, + ], "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.1" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@rspack/lite-tapable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.1.0.tgz", - "integrity": "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==", - "license": "MIT" - }, - "node_modules/@rspack/plugin-react-refresh": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.6.1.tgz", - "integrity": "sha512-eqqW5645VG3CzGzFgNg5HqNdHVXY+567PGjtDhhrM8t67caxmsSzRmT5qfoEIfBcGgFkH9vEg7kzXwmCYQdQDw==", - "license": "MIT", - "dependencies": { - "error-stack-parser": "^2.1.4", - "html-entities": "^2.6.0" - }, - "peerDependencies": { - "react-refresh": ">=0.10.0 <1.0.0", - "webpack-hot-middleware": "2.x" - }, - "peerDependenciesMeta": { - "webpack-hot-middleware": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@secretlint/core": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@secretlint/core/-/core-13.0.2.tgz", - "integrity": "sha512-15vg+zCmjQuDFVoOPNt0TyEu0Z95eir2MO19++wG82yM/vbPtFu/m9qd6oh54ZOBXgMcchdGDTxMwJNDnCLxcA==", + "node_modules/@expressive-code/core": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.41.7.tgz", + "integrity": "sha512-ck92uZYZ9Wba2zxkiZLsZGi9N54pMSAVdrI9uW3Oo9AtLglD5RmrdTwbYPCT2S/jC36JGB2i+pnQtBm/Ib2+dg==", "license": "MIT", "dependencies": { - "@secretlint/profiler": "13.0.2", - "@secretlint/types": "13.0.2", - "debug": "^4.4.3", - "structured-source": "^4.0.0" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@secretlint/profiler": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@secretlint/profiler/-/profiler-13.0.2.tgz", - "integrity": "sha512-vGaLZCoi9KewOF+sM0iIEBviWaH9mls1HmQFBgEPq4fnvmVO4PfKIkVr4CcAFm3Msg4NjzFE2RBAGwRR+5HEmQ==", - "license": "MIT" - }, - "node_modules/@secretlint/secretlint-rule-preset-recommend": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@secretlint/secretlint-rule-preset-recommend/-/secretlint-rule-preset-recommend-13.0.2.tgz", - "integrity": "sha512-D03Kw51qOgffj9zNlJFZUarVmP8zGcCZNi7A14+vZtHskbbBPEsS/f09idb48rrlMSaRMBN29IkqfbmPyL9xtw==", - "license": "MIT", - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@secretlint/types": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@secretlint/types/-/types-13.0.2.tgz", - "integrity": "sha512-cAZjr6ZTKgSuJMLyTGDrUEtK3XEZa+JStIkD+DmdkT32VGAN+dQJiYr1So3XJopsKSrqhP5kjZKT8WWtftZIpQ==", - "license": "MIT", - "engines": { - "node": ">=22.0.0" + "@ctrl/tinycolor": "^4.0.4", + "hast-util-select": "^6.0.2", + "hast-util-to-html": "^9.0.1", + "hast-util-to-text": "^4.0.1", + "hastscript": "^9.0.0", + "postcss": "^8.4.38", + "postcss-nested": "^6.0.1", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1" } }, - "node_modules/@selderee/plugin-htmlparser2": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", - "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", + "node_modules/@expressive-code/plugin-frames": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.41.7.tgz", + "integrity": "sha512-diKtxjQw/979cTglRFaMCY/sR6hWF0kSMg8jsKLXaZBSfGS0I/Hoe7Qds3vVEgeoW+GHHQzMcwvgx/MOIXhrTA==", "license": "MIT", "dependencies": { - "domhandler": "^5.0.3", - "selderee": "^0.11.0" - }, - "funding": { - "url": "https://ko-fi.com/killymxi" + "@expressive-code/core": "^0.41.7" } }, - "node_modules/@shikijs/core": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz", - "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", + "node_modules/@expressive-code/plugin-shiki": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.41.7.tgz", + "integrity": "sha512-DL605bLrUOgqTdZ0Ot5MlTaWzppRkzzqzeGEu7ODnHF39IkEBbFdsC7pbl3LbUQ1DFtnfx6rD54k/cdofbW6KQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.5" + "@expressive-code/core": "^0.41.7", + "shiki": "^3.2.2" } }, - "node_modules/@shikijs/engine-javascript": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz", - "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", + "node_modules/@expressive-code/plugin-text-markers": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.41.7.tgz", + "integrity": "sha512-Ewpwuc5t6eFdZmWlFyeuy3e1PTQC0jFvw2Q+2bpcWXbOZhPLsT7+h8lsSIJxb5mS7wZko7cKyQ2RLYDyK6Fpmw==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.4" + "@expressive-code/core": "^0.41.7" } }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", - "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "node_modules/@floating-ui/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0", - "@shikijs/vscode-textmate": "^10.0.2" + "@floating-ui/utils": "^0.2.12" } }, - "node_modules/@shikijs/langs": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", - "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "node_modules/@floating-ui/dom": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0" + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" } }, - "node_modules/@shikijs/primitive": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.3.1.tgz", - "integrity": "sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A==", + "node_modules/@floating-ui/react": { + "version": "0.27.20", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.20.tgz", + "integrity": "sha512-CMqMy7OaXl9W0eq1Uy7L7i2Y/anPvHmFmESd2CEw0t5YvZhcVCeo4MBevAmswRllX7Y2dEidA4ozGPunLSTQpw==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.3.1", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" + "@floating-ui/react-dom": "^2.1.9", + "@floating-ui/utils": "^0.2.12", + "tabbable": "^6.0.0" }, - "engines": { - "node": ">=20" + "peerDependencies": { + "react": ">=17.0.0", + "react-dom": ">=17.0.0" } }, - "node_modules/@shikijs/primitive/node_modules/@shikijs/types": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.3.1.tgz", - "integrity": "sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g==", + "node_modules/@floating-ui/react-dom": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", "license": "MIT", "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" + "@floating-ui/dom": "^1.8.0" }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/themes": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", - "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.23.0" - } - }, - "node_modules/@shikijs/types": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", - "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "node_modules/@floating-ui/utils": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", "license": "MIT" }, - "node_modules/@sindresorhus/is": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", - "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT", "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@speed-highlight/core": { - "version": "1.2.17", - "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.17.tgz", - "integrity": "sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg==", - "license": "CC0-1.0" - }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "license": "MIT" - }, - "node_modules/@standard-schema/utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", - "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", - "license": "MIT", - "peer": true - }, - "node_modules/@tailwindcss/node": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.2.tgz", - "integrity": "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==", - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "5.21.6", - "jiti": "^2.7.0", - "lightningcss": "1.32.0", - "magic-string": "^0.30.21", - "source-map-js": "^1.2.1", - "tailwindcss": "4.3.2" } }, - "node_modules/@tailwindcss/oxide": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.2.tgz", - "integrity": "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag==", - "license": "MIT", + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 20" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.3.2", - "@tailwindcss/oxide-darwin-arm64": "4.3.2", - "@tailwindcss/oxide-darwin-x64": "4.3.2", - "@tailwindcss/oxide-freebsd-x64": "4.3.2", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2", - "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2", - "@tailwindcss/oxide-linux-arm64-musl": "4.3.2", - "@tailwindcss/oxide-linux-x64-gnu": "4.3.2", - "@tailwindcss/oxide-linux-x64-musl": "4.3.2", - "@tailwindcss/oxide-wasm32-wasi": "4.3.2", - "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2", - "@tailwindcss/oxide-win32-x64-msvc": "4.3.2" + "@img/sharp-libvips-darwin-arm64": "1.2.4" } }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.2.tgz", - "integrity": "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==", + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", "cpu": [ - "arm64" + "x64" ], - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ - "android" + "darwin" ], "engines": { - "node": ">= 20" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" } }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.2.tgz", - "integrity": "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==", - "cpu": [ - "arm64" - ], - "license": "MIT", + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.2.tgz", + "integrity": "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==", + "license": "Apache-2.0", "optional": true, "os": [ - "darwin" + "freebsd" ], + "dependencies": { + "@img/sharp-wasm32": "0.35.2" + }, "engines": { - "node": ">= 20" + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.2.tgz", - "integrity": "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==", + "node_modules/@img/sharp-freebsd-wasm32/node_modules/@img/sharp-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz", + "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", "cpu": [ - "x64" + "arm64" ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" ], - "engines": { - "node": ">= 20" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.2.tgz", - "integrity": "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==", + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", "cpu": [ "x64" ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ - "freebsd" + "darwin" ], - "engines": { - "node": ">= 20" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.2.tgz", - "integrity": "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==", + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", "cpu": [ "arm" ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "node": ">= 20" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.2.tgz", - "integrity": "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==", + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "node": ">= 20" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.2.tgz", - "integrity": "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==", + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", "cpu": [ - "arm64" - ], - "libc": [ - "musl" + "ppc64" ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "node": ">= 20" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.2.tgz", - "integrity": "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==", + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", "cpu": [ - "x64" - ], - "libc": [ - "glibc" + "riscv64" ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "node": ">= 20" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.2.tgz", - "integrity": "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==", + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", "cpu": [ - "x64" - ], - "libc": [ - "musl" + "s390x" ], - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "node": ">= 20" + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.2.tgz", - "integrity": "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", "cpu": [ - "wasm32" + "x64" ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.11.1", - "@emnapi/runtime": "^1.11.1", - "@emnapi/wasi-threads": "^1.2.2", - "@napi-rs/wasm-runtime": "^1.1.4", - "@tybys/wasm-util": "^0.10.2", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.11.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.11.1", - "inBundle": true, - "license": "MIT", + "license": "LGPL-3.0-or-later", "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "inBundle": true, - "license": "MIT", + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "inBundle": true, - "license": "MIT", + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.1" - }, + "os": [ + "linux" + ], "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "url": "https://opencollective.com/libvips" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "inBundle": true, - "license": "MIT", + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.1", - "inBundle": true, - "license": "0BSD", - "optional": true - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz", - "integrity": "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==", + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", "cpu": [ "arm64" ], - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ - "win32" + "linux" ], "engines": { - "node": ">= 20" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" } }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.2.tgz", - "integrity": "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==", + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", "cpu": [ - "x64" + "ppc64" ], - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ - "win32" + "linux" ], "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.2.tgz", - "integrity": "sha512-eHpMeX4JXfVNJDEcsouTeCBubJBTcTLigeaw/NTUW6PB5ATKKXdyonnXgTBX2VuRbjz1hjfz6C5XAhr52ImQXA==", - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.3.2", - "@tailwindcss/oxide": "4.3.2", - "tailwindcss": "4.3.2" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7 || ^8" + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" } }, - "node_modules/@treeseed/core": { - "version": "0.12.59", - "resolved": "https://registry.npmjs.org/@treeseed/core/-/core-0.12.59.tgz", - "integrity": "sha512-vDLbM5PZRdHp+sAckVTpOGv1LLknXcaxZ9dG6CqplBm3Wa+vNhU+nQjzFf7B+BfXdcUZXDjAJBSUheQCfdvPnw==", - "license": "AGPL-3.0-only", - "dependencies": { - "@astrojs/check": "^0.9.8", - "@astrojs/cloudflare": "^12.6.13", - "@astrojs/markdown-remark": "^6.3.11", - "@astrojs/mdx": "^4.3.14", - "@astrojs/react": "^4.4.2", - "@astrojs/sitemap": "3.7.0", - "@astrojs/starlight": "0.37.6", - "@tailwindcss/vite": "^4.1.4", - "@treeseed/sdk": "0.12.62", - "@treeseed/ui": "0.12.17", - "astro": "^5.6.1", - "esbuild": "^0.28.0", - "katex": "^0.16.22", - "nodemailer": "^8.0.4", - "rehype-katex": "^7.0.1", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.1", - "remark-math": "^6.0.0", - "remark-mdx": "^3.1.1", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "tailwindcss": "^4.1.4", - "typescript": "^5.9.3", - "unified": "^11.0.5", - "vitest": "^4.1.2", - "wrangler": "^4.80.0", - "yaml": "^2.8.1" + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "bin": { - "treeseed-workspace-bootstrap": "dist/scripts/workspace-bootstrap.js" + "funding": { + "url": "https://opencollective.com/libvips" }, - "engines": { - "node": ">=22" + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" } }, - "node_modules/@treeseed/core/node_modules/@astrojs/cloudflare": { - "version": "12.6.13", - "resolved": "https://registry.npmjs.org/@astrojs/cloudflare/-/cloudflare-12.6.13.tgz", - "integrity": "sha512-oKaCyiovyQr183r9U93787Ju1zwk+rRMgPnLTwCLckHmOUK7sltA1Gp4LSGt8oNMgqQS6jR7uRdfQ/NPul37QA==", - "license": "MIT", - "dependencies": { - "@astrojs/internal-helpers": "0.7.6", - "@astrojs/underscore-redirects": "1.0.0", - "@cloudflare/workers-types": "^4.20260116.0", - "tinyglobby": "^0.2.15", - "vite": "^6.4.1", - "wrangler": "4.59.2" + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "peerDependencies": { - "astro": "^5.7.0" + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" } }, - "node_modules/@treeseed/core/node_modules/@astrojs/cloudflare/node_modules/esbuild": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", - "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.0", - "@esbuild/android-arm": "0.27.0", - "@esbuild/android-arm64": "0.27.0", - "@esbuild/android-x64": "0.27.0", - "@esbuild/darwin-arm64": "0.27.0", - "@esbuild/darwin-x64": "0.27.0", - "@esbuild/freebsd-arm64": "0.27.0", - "@esbuild/freebsd-x64": "0.27.0", - "@esbuild/linux-arm": "0.27.0", - "@esbuild/linux-arm64": "0.27.0", - "@esbuild/linux-ia32": "0.27.0", - "@esbuild/linux-loong64": "0.27.0", - "@esbuild/linux-mips64el": "0.27.0", - "@esbuild/linux-ppc64": "0.27.0", - "@esbuild/linux-riscv64": "0.27.0", - "@esbuild/linux-s390x": "0.27.0", - "@esbuild/linux-x64": "0.27.0", - "@esbuild/netbsd-arm64": "0.27.0", - "@esbuild/netbsd-x64": "0.27.0", - "@esbuild/openbsd-arm64": "0.27.0", - "@esbuild/openbsd-x64": "0.27.0", - "@esbuild/openharmony-arm64": "0.27.0", - "@esbuild/sunos-x64": "0.27.0", - "@esbuild/win32-arm64": "0.27.0", - "@esbuild/win32-ia32": "0.27.0", - "@esbuild/win32-x64": "0.27.0" + "@img/sharp-libvips-linux-x64": "1.2.4" } }, - "node_modules/@treeseed/core/node_modules/@astrojs/cloudflare/node_modules/wrangler": { - "version": "4.59.2", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.59.2.tgz", - "integrity": "sha512-Z4xn6jFZTaugcOKz42xvRAYKgkVUERHVbuCJ5+f+gK+R6k12L02unakPGOA0L0ejhUl16dqDjKe4tmL9sedHcw==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@cloudflare/kv-asset-handler": "0.4.2", - "@cloudflare/unenv-preset": "2.10.0", - "blake3-wasm": "2.1.5", - "esbuild": "0.27.0", - "miniflare": "4.20260114.0", - "path-to-regexp": "6.3.0", - "unenv": "2.0.0-rc.24", - "workerd": "1.20260114.0" - }, - "bin": { - "wrangler": "bin/wrangler.js", - "wrangler2": "bin/wrangler.js" - }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=20.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "peerDependencies": { - "@cloudflare/workers-types": "^4.20260114.0" + "funding": { + "url": "https://opencollective.com/libvips" }, - "peerDependenciesMeta": { - "@cloudflare/workers-types": { - "optional": true - } + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" } }, - "node_modules/@treeseed/core/node_modules/@astrojs/mdx": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.3.14.tgz", - "integrity": "sha512-FBrqJQORVm+rkRa2TS5CjU9PBA6hkhrwLVBSS9A77gN2+iehvjq1w6yya/d0YKC7osiVorKkr3Qd9wNbl0ZkGA==", - "license": "MIT", - "dependencies": { - "@astrojs/markdown-remark": "6.3.11", - "@mdx-js/mdx": "^3.1.1", - "acorn": "^8.15.0", - "es-module-lexer": "^1.7.0", - "estree-util-visit": "^2.0.0", - "hast-util-to-html": "^9.0.5", - "piccolore": "^0.1.3", - "rehype-raw": "^7.0.0", - "remark-gfm": "^4.0.1", - "remark-smartypants": "^3.0.2", - "source-map": "^0.7.6", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.3" - }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "peerDependencies": { - "astro": "^5.0.0" + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" } }, - "node_modules/@treeseed/core/node_modules/@astrojs/starlight": { - "version": "0.37.6", - "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.37.6.tgz", - "integrity": "sha512-wQrKwH431q+8FsLBnNQeG+R36TMtEGxTQ2AuiVpcx9APcazvL3n7wVW8mMmYyxX0POjTnxlcWPkdMGR3Yj1L+w==", - "license": "MIT", + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, "dependencies": { - "@astrojs/markdown-remark": "^6.3.1", - "@astrojs/mdx": "^4.2.3", - "@astrojs/sitemap": "^3.3.0", - "@pagefind/default-ui": "^1.3.0", - "@types/hast": "^3.0.4", - "@types/js-yaml": "^4.0.9", - "@types/mdast": "^4.0.4", - "astro-expressive-code": "^0.41.1", - "bcp-47": "^2.1.0", - "hast-util-from-html": "^2.0.1", - "hast-util-select": "^6.0.2", - "hast-util-to-string": "^3.0.0", - "hastscript": "^9.0.0", - "i18next": "^23.11.5", - "js-yaml": "^4.1.0", - "klona": "^2.0.6", - "magic-string": "^0.30.17", - "mdast-util-directive": "^3.0.0", - "mdast-util-to-markdown": "^2.1.0", - "mdast-util-to-string": "^4.0.0", - "pagefind": "^1.3.0", - "rehype": "^13.0.1", - "rehype-format": "^5.0.0", - "remark-directive": "^3.0.0", - "ultrahtml": "^1.6.0", - "unified": "^11.0.5", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.2" + "@emnapi/runtime": "^1.7.0" }, - "peerDependencies": { - "astro": "^5.5.0" + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@treeseed/core/node_modules/@astrojs/telemetry": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", - "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", - "license": "MIT", + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.2.tgz", + "integrity": "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0", + "optional": true, "dependencies": { - "ci-info": "^4.2.0", - "debug": "^4.4.0", - "dlv": "^1.1.3", - "dset": "^3.1.4", - "is-docker": "^3.0.0", - "is-wsl": "^3.1.0", - "which-pm-runs": "^1.1.0" + "@img/sharp-wasm32": "0.35.2" }, "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@treeseed/core/node_modules/@cloudflare/kv-asset-handler": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.2.tgz", - "integrity": "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==", - "license": "MIT OR Apache-2.0", + "node_modules/@img/sharp-webcontainers-wasm32/node_modules/@img/sharp-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz", + "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@treeseed/core/node_modules/@cloudflare/unenv-preset": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.10.0.tgz", - "integrity": "sha512-/uII4vLQXhzCAZzEVeYAjFLBNg2nqTJ1JGzd2lRF6ItYe6U2zVoYGfeKpGx/EkBF6euiU+cyBXgMdtJih+nQ6g==", - "license": "MIT OR Apache-2.0", - "peerDependencies": { - "unenv": "2.0.0-rc.24", - "workerd": "^1.20251221.0" + "node": ">=20.9.0" }, - "peerDependenciesMeta": { - "workerd": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@treeseed/core/node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20260114.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260114.0.tgz", - "integrity": "sha512-HNlsRkfNgardCig2P/5bp/dqDECsZ4+NU5XewqArWxMseqt3C5daSuptI620s4pn7Wr0ZKg7jVLH0PDEBkA+aA==", + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", "cpu": [ - "x64" + "arm64" ], - "license": "Apache-2.0", + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ - "darwin" + "win32" ], "engines": { - "node": ">=16" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@treeseed/core/node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20260114.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260114.0.tgz", - "integrity": "sha512-qyE1UdFnAlxzb+uCfN/d9c8icch7XRiH49/DjoqEa+bCDihTuRS7GL1RmhVIqHJhb3pX3DzxmKgQZBDBL83Inw==", + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", "cpu": [ - "arm64" + "ia32" ], - "license": "Apache-2.0", + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ - "darwin" + "win32" ], "engines": { - "node": ">=16" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@treeseed/core/node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20260114.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260114.0.tgz", - "integrity": "sha512-Z0BLvAj/JPOabzads2ddDEfgExWTlD22pnwsuNbPwZAGTSZeQa3Y47eGUWyHk+rSGngknk++S7zHTGbKuG7RRg==", + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", "cpu": [ "x64" ], - "license": "Apache-2.0", + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ - "linux" + "win32" ], "engines": { - "node": ">=16" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@treeseed/core/node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20260114.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260114.0.tgz", - "integrity": "sha512-kPUmEtUxUWlr9PQ64kuhdK0qyo8idPe5IIXUgi7xCD7mDd6EOe5J7ugDpbfvfbYKEjx4DpLvN2t45izyI/Sodw==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lexical/a11y": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/a11y/-/a11y-0.48.0.tgz", + "integrity": "sha512-18W4ehyipkUim4YVoDZitoH63Om3j6iCN4c84zdqE9RgkWf/PE4rvI/8BHTm6Ni7NkVE14nimXgkpaP5ok15zA==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@lexical/clipboard": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.48.0.tgz", + "integrity": "sha512-xO2trk6+yBl8XXa/VNe20kXczmPxFoWtUHjidbBLEtlGBj+mo63pJj6H5o/WlZsoMKmIOJxwxsn2ejrS8G0/7A==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/list": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "@types/trusted-types": "^2.0.7", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@lexical/code-core": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/code-core/-/code-core-0.48.0.tgz", + "integrity": "sha512-+O1Ge06AuSo6+r8R2Xk6SkWG07H5/e4K/Scw9aqCM/BRjITxgvFTHTNvgQbaobCsP0uBJiwW1+ZGeWAWcBCY4w==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@lexical/devtools-core": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.48.0.tgz", + "integrity": "sha512-4kvKWW6ebgQnJNLXPLmw7dqgSChvzYIBNYtfuR6c48Sw+V/QXQTWqfIUbCIe5X4uG8EEXd5O/udXaJx7GBuP+w==", + "license": "MIT", + "dependencies": { + "@lexical/html": "0.48.0", + "@lexical/link": "0.48.0", + "@lexical/mark": "0.48.0", + "@lexical/table": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "react": ">=18.x", + "react-dom": ">=18.x", + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20260114.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260114.0.tgz", - "integrity": "sha512-MJnKgm6i1jZGyt2ZHQYCnRlpFTEZcK2rv9y7asS3KdVEXaDgGF8kOns5u6YL6/+eMogfZuHRjfDS+UqRTUYIFA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16" + "node_modules/@lexical/dragon": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.48.0.tgz", + "integrity": "sha512-uPuu7fVca9vmL/Oz30CRZ7FIPIodwMrTgNsRmV8jE6Qd6a7RNiTW7r3+EhbhIdkLb/sjcWsYyOMyUR1TJAB0wQ==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@cloudflare/workers-types": { - "version": "4.20260702.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz", - "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==", - "license": "MIT OR Apache-2.0" - }, - "node_modules/@treeseed/core/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", - "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", - "cpu": [ - "ppc64" - ], + "node_modules/@lexical/extension": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/extension/-/extension-0.48.0.tgz", + "integrity": "sha512-4uBObgz84mVbQWiumndmIhkuJL0ojHiMwFSvSUM/FCo1YMVIZvpI56blI0y+2Vix/oLui9EgVQSJjjWV4NAszw==", "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "@preact/signals-core": "^1.14.1", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/android-arm": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", - "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", - "cpu": [ - "arm" - ], + "node_modules/@lexical/hashtag": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.48.0.tgz", + "integrity": "sha512-hPQtdnbVoNAFsmfnCGfgY7mDbvk6mIznlCRmIR7tLeQKXqz/0Tb6eH3W24EESk9hAF8wFUYNKWE1/Kb3Hl2vEQ==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/text": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/android-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", - "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", - "cpu": [ - "arm64" - ], + "node_modules/@lexical/history": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.48.0.tgz", + "integrity": "sha512-NllvUfO+u3mfi5uC8k2CodwdzeeopFFVtMZ/NMifzFbZFysdWi9m9mqfO46NrEA1rSFOydyefv6oMzC8ULXInA==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/android-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", - "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", - "cpu": [ - "x64" - ], + "node_modules/@lexical/html": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.48.0.tgz", + "integrity": "sha512-uBxlgKl4YgSNEgHJSshdBqtGDzruWdx1ewop+u6faT67qHUdP3P0cUXIrG6NToDWvsL6fzCstAbN76PMER1Pnw==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", - "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", - "cpu": [ - "arm64" - ], + "node_modules/@lexical/internal": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/internal/-/internal-0.48.0.tgz", + "integrity": "sha512-sRwg53K7N0ZQ7KNAvcCY38LSwGizbXP1zlR1lIojZp0GoqHWNvR+vL49t1wYXu1nXx3Osf4ilHHm+aGcwq5hTw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/darwin-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", - "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", - "cpu": [ - "x64" - ], + "node_modules/@lexical/link": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.48.0.tgz", + "integrity": "sha512-E0UDmNLUXs/yMCnnE7hbFO0CvhWghmqa+qqPksFfzLkpMHdPpdS1yg59YEbYoNHLi/DXIu4cFRvpHIEuooxwNg==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", - "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", - "cpu": [ - "arm64" - ], + "node_modules/@lexical/list": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.48.0.tgz", + "integrity": "sha512-9Qe/Vur44v9F9enj55SUzf79FVsijcGOQug7SpiIU8ekLr7JNzcilKYBYcZ6etGEo7bqQHsYMHXeJcSBbCI2zA==", "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", - "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", - "cpu": [ - "x64" - ], + "node_modules/@lexical/mark": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.48.0.tgz", + "integrity": "sha512-DTtypWvnYSXyNUxEmsUnh4y0xXkmdk8Y72EZl8WDHcCwjqaLJlUakH7p/TuSJczs3uVSaoJzu0yh7oGkP1Vsvw==", "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-arm": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", - "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", - "cpu": [ - "arm" - ], + "node_modules/@lexical/markdown": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.48.0.tgz", + "integrity": "sha512-1WasBenW4bEsa5xtnycVo8G2hcxIqyYLn3/r98yD2Y+54ZyeFuIQfOeJYhIgCh4YkKpfqyrFwkMQwAOsQDqZjA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/code-core": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/link": "0.48.0", + "@lexical/list": "0.48.0", + "@lexical/rich-text": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/text": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", - "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", - "cpu": [ - "arm64" - ], + "node_modules/@lexical/overflow": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.48.0.tgz", + "integrity": "sha512-1YEvMz2tW3EbwrON9mjrkjMVl/vdTcPYSn9P1j6mf5gj0LOoLDNI4TbvSD4SViy+TDghxNdG8YdCISyU2b4YKA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-ia32": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", - "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", - "cpu": [ - "ia32" - ], + "node_modules/@lexical/plain-text": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.48.0.tgz", + "integrity": "sha512-q4f/4VZKVgCrIW2FhDFR2RII1BU0ljedPgEmJ8XQn1zc+JOFPom8Lp0lV5nyEvZaAJYwM/TfoJ9g2V7ESFKznA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/clipboard": "0.48.0", + "@lexical/dragon": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-loong64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", - "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "node_modules/@lexical/react": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/react/-/react-0.48.0.tgz", + "integrity": "sha512-uVh9/QSrbtjLjVbxfJ+sfiMyhUq/rv7H6uBEVDDIw1rkZJSDY1fvf/CX+dyKgwcDFjKQZ8/9i5f9UCVPeQ01hA==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.27.19", + "@lexical/a11y": "0.48.0", + "@lexical/devtools-core": "0.48.0", + "@lexical/dragon": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/hashtag": "0.48.0", + "@lexical/history": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/link": "0.48.0", + "@lexical/list": "0.48.0", + "@lexical/mark": "0.48.0", + "@lexical/markdown": "0.48.0", + "@lexical/overflow": "0.48.0", + "@lexical/plain-text": "0.48.0", + "@lexical/rich-text": "0.48.0", + "@lexical/table": "0.48.0", + "@lexical/text": "0.48.0", + "@lexical/utils": "0.48.0", + "@lexical/yjs": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "react": ">=18.x", + "react-dom": ">=18.x", + "typescript": ">=5.2", + "yjs": ">=13.5.22" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "yjs": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", - "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", - "cpu": [ - "mips64el" - ], + "node_modules/@lexical/rich-text": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.48.0.tgz", + "integrity": "sha512-QMXFnwCKAQ4yzxvx5FwmANcx3K+NaBkGTxAVD8s8pOKDD/U5rzDS1iIvhH6TLWaFp7VzvLmLB+Sl1Ie/RnkaDQ==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/clipboard": "0.48.0", + "@lexical/dragon": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", - "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", - "cpu": [ - "ppc64" - ], + "node_modules/@lexical/selection": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.48.0.tgz", + "integrity": "sha512-Uc0wTrEtHcYK6z/aHHjkgH3vX/R4Bf8mO+qH3VbxfSAKYzNYktM0j+ZGdq5kIEL4frnw/9SulNCXlH7xpjuDgA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/internal": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", - "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", - "cpu": [ - "riscv64" - ], + "node_modules/@lexical/table": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.48.0.tgz", + "integrity": "sha512-t9Mz7q6ODLUz0lG5Xn9EY/5YiVpTHCqlPQP4EtFXlnBQT3DuKeDS3cC0Cn8sGSZc11YY5OLDfWpB64Frs9BL3g==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/clipboard": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-s390x": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", - "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", - "cpu": [ - "s390x" - ], + "node_modules/@lexical/text": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/text/-/text-0.48.0.tgz", + "integrity": "sha512-ktTMRbsX4wKxdG2OpZCkrqtt8k9Vg/ZpWdukOQ0r1xPRtCuL1T+q91l7cy2ywIuCfMGYS0aoZGB4LdpUMe/H1g==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/internal": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/linux-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", - "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", - "cpu": [ - "x64" - ], + "node_modules/@lexical/utils": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.48.0.tgz", + "integrity": "sha512-W4k4P+y6jmRfna8+ad4X+iMd5h8es5PC3bUw5tbi7MRApxaaFG/0w+uJiZVSwbT2Q6JnA2xhBaqzPgt/Gn6djg==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/internal": "0.48.0", + "@lexical/selection": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", - "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", - "cpu": [ - "arm64" - ], + "node_modules/@lexical/yjs": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.48.0.tgz", + "integrity": "sha512-fFsE8EnPM/2KK9rMJ0z6T+Da5UW5V4P+XiAA03LoHTY5YQ/Oy8Q0i7Wcmocv/B/SpsY2o8g07euZEfudl9MVKA==", "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lexical/internal": "0.48.0", + "@lexical/selection": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2", + "yjs": ">=13.5.22" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", - "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", - "cpu": [ - "x64" - ], + "node_modules/@lezer/common": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz", + "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", + "license": "MIT" + }, + "node_modules/@lezer/cpp": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.6.tgz", + "integrity": "sha512-vh9gWWJOXFVY8HBHK3Twzq8MgwG2iN4GSyzBP9sCGTe37P15x2R14VaBQk0VA0ezTRN1KHYBBsHhvpGZ2Xy/pA==", "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", - "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", - "cpu": [ - "arm64" - ], + "node_modules/@lezer/css": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.3.6.tgz", + "integrity": "sha512-YJE78Wcg+zX8f10hiHWQ4Az48Qr/c13eId0VtRQYLBpxHDmDeSrXIlkbl+fJGW42rWC/uoUco9mhBZeVWP/A1g==", "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.0" } }, - "node_modules/@treeseed/core/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", - "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", - "cpu": [ - "x64" - ], + "node_modules/@lezer/go": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lezer/go/-/go-1.0.1.tgz", + "integrity": "sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ==", "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.0" } }, - "node_modules/@treeseed/core/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", - "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", - "cpu": [ - "arm64" - ], + "node_modules/@lezer/highlight": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz", + "integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==", "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.3.0" } }, - "node_modules/@treeseed/core/node_modules/@esbuild/sunos-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", - "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", - "cpu": [ - "x64" - ], + "node_modules/@lezer/html": { + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.13.tgz", + "integrity": "sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==", "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/@esbuild/win32-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", - "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", - "cpu": [ - "arm64" - ], + "node_modules/@lezer/java": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.3.tgz", + "integrity": "sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/@esbuild/win32-ia32": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", - "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", - "cpu": [ - "ia32" - ], + "node_modules/@lezer/javascript": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.4.tgz", + "integrity": "sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" } }, - "node_modules/@treeseed/core/node_modules/@esbuild/win32-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", - "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", - "cpu": [ - "x64" - ], + "node_modules/@lezer/json": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", + "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/astro": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/astro/-/astro-5.18.2.tgz", - "integrity": "sha512-TnFwLnAXty5MXKPDGuKXqK4AMBXG+FH6RUdK7Oyc3gyfNoFIthT+4eRbzOK43bdRlLaZuxgciDSjgtggZ3OtGQ==", + "node_modules/@lezer/lr": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz", + "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==", "license": "MIT", "dependencies": { - "@astrojs/compiler": "^2.13.0", - "@astrojs/internal-helpers": "0.7.6", - "@astrojs/markdown-remark": "6.3.11", - "@astrojs/telemetry": "3.3.0", - "@capsizecss/unpack": "^4.0.0", - "@oslojs/encoding": "^1.1.0", - "@rollup/pluginutils": "^5.3.0", - "acorn": "^8.15.0", - "aria-query": "^5.3.2", - "axobject-query": "^4.1.0", - "boxen": "8.0.1", - "ci-info": "^4.3.1", - "clsx": "^2.1.1", - "common-ancestor-path": "^1.0.1", - "cookie": "^1.1.1", - "cssesc": "^3.0.0", - "debug": "^4.4.3", - "deterministic-object-hash": "^2.0.2", - "devalue": "^5.6.2", - "diff": "^8.0.3", - "dlv": "^1.1.3", - "dset": "^3.1.4", - "es-module-lexer": "^1.7.0", - "esbuild": "^0.27.3", - "estree-walker": "^3.0.3", - "flattie": "^1.1.1", - "fontace": "~0.4.0", - "github-slugger": "^2.0.0", - "html-escaper": "3.0.3", - "http-cache-semantics": "^4.2.0", - "import-meta-resolve": "^4.2.0", - "js-yaml": "^4.1.1", - "magic-string": "^0.30.21", - "magicast": "^0.5.1", - "mrmime": "^2.0.1", - "neotraverse": "^0.6.18", - "p-limit": "^6.2.0", - "p-queue": "^8.1.1", - "package-manager-detector": "^1.6.0", - "piccolore": "^0.1.3", - "picomatch": "^4.0.3", - "prompts": "^2.4.2", - "rehype": "^13.0.2", - "semver": "^7.7.3", - "shiki": "^3.21.0", - "smol-toml": "^1.6.0", - "svgo": "^4.0.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tsconfck": "^3.1.6", - "ultrahtml": "^1.6.0", - "unifont": "~0.7.3", - "unist-util-visit": "^5.0.0", - "unstorage": "^1.17.4", - "vfile": "^6.0.3", - "vite": "^6.4.1", - "vitefu": "^1.1.1", - "xxhash-wasm": "^1.1.0", - "yargs-parser": "^21.1.1", - "yocto-spinner": "^0.2.3", - "zod": "^3.25.76", - "zod-to-json-schema": "^3.25.1", - "zod-to-ts": "^1.2.0" - }, - "bin": { - "astro": "astro.js" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/astrodotbuild" - }, - "optionalDependencies": { - "sharp": "^0.34.0" + "@lezer/common": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", - "cpu": [ - "ppc64" - ], + "node_modules/@lezer/markdown": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.7.2.tgz", + "integrity": "sha512-iTkYvoVcKt3WkeL7qUDyXHONZEwLio4wj8KTNi2dnjQEXBZKMV63BpQrPqfsM+OkvuRbiSTAcycYAsQzLhRNoQ==", "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.5.0", + "@lezer/highlight": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", - "cpu": [ - "arm" - ], + "node_modules/@lezer/php": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.5.tgz", + "integrity": "sha512-W7asp9DhM6q0W6DYNwIkLSKOvxlXRrif+UXBMxzsJUuqmhE7oVU+gS3THO4S/Puh7Xzgm858UNaFi6dxTP8dJA==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.1.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", - "cpu": [ - "arm64" - ], + "node_modules/@lezer/python": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.19.tgz", + "integrity": "sha512-MhQIURHRytsNzP/YXnqpYKW6la6voAH3kyplTOOiCdjyFY6cWWGFVmYVdHIPrElqSDf4iCDktQCockB9FxuhzQ==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", - "cpu": [ - "x64" - ], + "node_modules/@lezer/rust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.2.tgz", + "integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", - "cpu": [ - "arm64" - ], + "node_modules/@lezer/sass": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lezer/sass/-/sass-1.1.0.tgz", + "integrity": "sha512-3mMGdCTUZ/84ArHOuXWQr37pnf7f+Nw9ycPUeKX+wu19b7pSMcZGLbaXwvD2APMBDOGxPmpK/O6S1v1EvLoqgQ==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", - "cpu": [ - "x64" - ], + "node_modules/@lezer/xml": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.6.tgz", + "integrity": "sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/yaml": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@lezer/yaml/-/yaml-1.0.4.tgz", + "integrity": "sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.4.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", - "cpu": [ - "arm64" - ], + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.4.tgz", + "integrity": "sha512-Wy0V7+SGUjnF9/TkiM1hKVDPj7jKXduPNboMVtHTA8dySMURWqfg/JZ9E2Sq8JgSJmkl7k7Qe9FLeMSrSraWmQ==", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", - "cpu": [ - "x64" - ], + "node_modules/@mdx-js/mdx/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@types/estree": "^1.0.0" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", - "cpu": [ - "arm" - ], + "node_modules/@mdxeditor/editor": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@mdxeditor/editor/-/editor-4.2.2.tgz", + "integrity": "sha512-qQDBNDnp3y+ddLYCWyLTs7YNrDSd+4PyI6FlXrwKdYwGWSNkcmjzF+KuWblMVuAWWQrXlekLOQPbMWUni1nx1A==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@codemirror/commands": "^6.2.4", + "@codemirror/lang-markdown": "^6.2.3", + "@codemirror/language-data": "^6.5.1", + "@codemirror/merge": "^6.4.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.23.0", + "@lexical/clipboard": "^0.48.0", + "@lexical/extension": "^0.48.0", + "@lexical/history": "^0.48.0", + "@lexical/link": "^0.48.0", + "@lexical/list": "^0.48.0", + "@lexical/markdown": "^0.48.0", + "@lexical/plain-text": "^0.48.0", + "@lexical/react": "^0.48.0", + "@lexical/rich-text": "^0.48.0", + "@lexical/selection": "^0.48.0", + "@lexical/utils": "^0.48.0", + "@mdxeditor/gurx": "^1.2.4", + "@radix-ui/colors": "^3.0.0", + "@radix-ui/react-dialog": "^1.1.11", + "@radix-ui/react-icons": "^1.3.2", + "@radix-ui/react-popover": "^1.1.11", + "@radix-ui/react-popper": "^1.2.4", + "@radix-ui/react-select": "^2.2.2", + "@radix-ui/react-toggle-group": "^1.1.7", + "@radix-ui/react-toolbar": "^1.1.7", + "@radix-ui/react-tooltip": "^1.2.4", + "classnames": "^2.3.2", + "cm6-theme-basic-light": "^0.2.0", + "codemirror": "^6.0.1", + "downshift": "^7.6.0", + "js-yaml": "4.3.1", + "lexical": "^0.48.0", + "mdast-util-directive": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-frontmatter": "^2.0.1", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-highlight-mark": "^1.2.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-to-markdown": "^2.1.0", + "micromark-extension-directive": "^3.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.1", + "micromark-extension-highlight-mark": "^1.2.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs": "^3.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.1", + "micromark-util-symbol": "^2.0.0", + "react-hook-form": "^7.56.1", + "unidiff": "^1.0.2" + }, "engines": { - "node": ">=18" + "node": ">=16" + }, + "peerDependencies": { + "react": ">= 18 || >= 19", + "react-dom": ">= 18 || >= 19" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", - "cpu": [ - "arm64" - ], + "node_modules/@mdxeditor/gurx": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@mdxeditor/gurx/-/gurx-1.2.4.tgz", + "integrity": "sha512-9ZykIFYhKaXaaSPCs1cuI+FvYDegJjbKwmA4ASE/zY+hJY6EYqvoye4esiO85CjhOw9aoD/izD/CU78/egVqmg==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": ">=16" + }, + "peerDependencies": { + "react": ">= 18 || >= 19", + "react-dom": ">= 18 || >= 19" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", "cpu": [ - "ia32" + "x64" ], "license": "MIT", "optional": true, @@ -7934,93 +4930,86 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^22.20 || ^24.12 || >=25" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", - "cpu": [ - "loong64" - ], + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@oxc-project/types": { + "version": "0.143.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.143.0.tgz", + "integrity": "sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "funding": { + "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "node_modules/@pagefind/darwin-arm64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.5.2.tgz", + "integrity": "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==", "cpu": [ - "mips64el" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } + "darwin" + ] }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "node_modules/@pagefind/darwin-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.5.2.tgz", + "integrity": "sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==", "cpu": [ - "ppc64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } + "darwin" + ] }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "node_modules/@pagefind/default-ui": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.5.2.tgz", + "integrity": "sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==", + "license": "MIT" + }, + "node_modules/@pagefind/freebsd-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.5.2.tgz", + "integrity": "sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==", "cpu": [ - "riscv64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } + "freebsd" + ] }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "node_modules/@pagefind/linux-arm64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.5.2.tgz", + "integrity": "sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==", "cpu": [ - "s390x" + "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=18" - } + ] }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "node_modules/@pagefind/linux-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.5.2.tgz", + "integrity": "sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==", "cpu": [ "x64" ], @@ -8028,456 +5017,894 @@ "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=18" - } + ] }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "node_modules/@pagefind/windows-arm64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/windows-arm64/-/windows-arm64-1.5.2.tgz", + "integrity": "sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } + "win32" + ] }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "node_modules/@pagefind/windows-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.5.2.tgz", + "integrity": "sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "win32" + ] + }, + "node_modules/@poppinss/colors": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", + "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", - "cpu": [ - "arm64" - ], + "node_modules/@poppinss/dumper": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", + "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/dumper/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", + "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", + "license": "MIT" + }, + "node_modules/@preact/signals-core": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.4.tgz", + "integrity": "sha512-HNB6HYeYKhQbJ1aKl+YRjrS4+QWHLKX6qKoUsfS/m0vqzsVaEBiZiaKbG/e+NKk2ch5ALQr/ihWaMHxiCuuWHA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/@radix-ui/colors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz", + "integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==", + "license": "MIT" + }, + "node_modules/@radix-ui/number": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.3.tgz", + "integrity": "sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.7.tgz", + "integrity": "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.15.tgz", + "integrity": "sha512-v4zggRcjadnI+ClKDuijlQEW4tw3NoaeHc/PwpKnLoLLKNUG4InLegkstooLcRIUWCs+8L22dGURCVuFfOKfnA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.10" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.15.tgz", + "integrity": "sha512-9W+B9NPF0NaaPh/1NJd3+KqsnlLqU9H7T2rvww+fp+T/evVXdNAyYcnfRQZFOjkR1ajQp3yORlqnI8soawLvNA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz", + "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.2.tgz", + "integrity": "sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.23.tgz", + "integrity": "sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.4.tgz", + "integrity": "sha512-5pzg4FGQNpExhnhT2zlrP1wZFaYCd1K0nYWoFAdcYoYK868IEigqMX3B3f8yIoRlAhAeDWciLI6ZdCKHF9P4Vg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.19.tgz", + "integrity": "sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-effect-event": "0.0.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.6.tgz", + "integrity": "sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.16.tgz", + "integrity": "sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", - "cpu": [ - "x64" - ], + "node_modules/@radix-ui/react-icons": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz", + "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==", "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", - "cpu": [ - "arm64" - ], + "node_modules/@radix-ui/react-id": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz", + "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==", "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" + "node_modules/@radix-ui/react-popover": { + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.23.tgz", + "integrity": "sha512-mw58MrBlyHWFisTOYignD0vf/3gdcgAR+9of1s9G/38CbFiUwH1nCDkc0AUM9IrXFgN5Ue8n45j9WCgyM1sbiQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", - "cpu": [ - "arm64" - ], + "node_modules/@radix-ui/react-popper": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.7.tgz", + "integrity": "sha512-UsJrrd7w4wuKKTdvd/DNERVlwSlUcyXzjhyDwBk+3aPOsCjOY6ZSbxuw8E6lZTjjfP8Cpd0J8VVkrYUWyGYXyg==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-rect": "1.1.4", + "@radix-ui/react-use-size": "1.1.4", + "@radix-ui/rect": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", - "cpu": [ - "ia32" - ], + "node_modules/@radix-ui/react-portal": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.17.tgz", + "integrity": "sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", - "cpu": [ - "x64" - ], + "node_modules/@radix-ui/react-presence": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.10.tgz", + "integrity": "sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/astro/node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", - "hasInstallScript": true, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.10.tgz", + "integrity": "sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==", "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "@radix-ui/react-slot": "1.3.3" }, - "engines": { - "node": ">=18" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", - "license": "ISC" + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.19.tgz", + "integrity": "sha512-V9jI6hDjT7l3jsCQD9bLNvDLM3tH/gdbOTp7Tefp3hbbgCGQoK7tUvrWiRlcoBHIZ809ElXwNQwVo0B98LuTXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@treeseed/core/node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "license": "MIT" + "node_modules/@radix-ui/react-select": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.3.7.tgz", + "integrity": "sha512-WFGImkmbzcfxeIwq/+4HvRN0pizBwbwQUED4I13ezQsDdfl38ZntN6TmR8XaSzPBqoCToe8rF75j6NPNDSzhbg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-previous": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.11", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@treeseed/core/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/@radix-ui/react-separator": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.15.tgz", + "integrity": "sha512-jOLO4lssEzWpoDu7G+Ze4VjwMRUBt291pnZD0gmalREZipnTX3wadQo7Fy48GCTfe14/YRN6rw/rOJqrE85Wxw==", "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" + "@radix-ui/react-primitive": "2.1.10" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, + "node_modules/@radix-ui/react-slot": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.3.tgz", + "integrity": "sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "node_modules/@radix-ui/react-toggle": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.18.tgz", + "integrity": "sha512-7lonPlKfSacd20GlOBx2ltuVKz9oqWYZz+oMQyOltw6t1y2nyftj2ZmwwUHYn49kqfDWcp8dNZm5NgV+5Z+mug==", "license": "MIT", - "bin": { - "is-docker": "cli.js" + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-controllable-state": "1.2.6" }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/miniflare": { - "version": "4.20260114.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260114.0.tgz", - "integrity": "sha512-QwHT7S6XqGdQxIvql1uirH/7/i3zDEt0B/YBXTYzMfJtVCR4+ue3KPkU+Bl0zMxvpgkvjh9+eCHhJbKEqya70A==", + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.19.tgz", + "integrity": "sha512-OtnwuSVjd1Ofi+AdnvhsjQdyuhCDwYs1w9RyB5BN/OavXOVQo42SYqQjwUnbPnaiPFBpQ9aX70dWeee+v2oBLA==", "license": "MIT", "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "sharp": "^0.34.5", - "undici": "7.14.0", - "workerd": "1.20260114.0", - "ws": "8.18.0", - "youch": "4.1.0-beta.10", - "zod": "^3.25.76" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-roving-focus": "1.1.19", + "@radix-ui/react-toggle": "1.1.18", + "@radix-ui/react-use-controllable-state": "1.2.6" }, - "bin": { - "miniflare": "bootstrap.js" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "engines": { - "node": ">=18.0.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/p-limit": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", - "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "node_modules/@radix-ui/react-toolbar": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.1.19.tgz", + "integrity": "sha512-Ph0IvtYw4VB12ZnZg+YtrGs8yJQsnizwo/zu0R4Y/nWugtJzA7Pg1eWeuDR9+LSqn+xjamss+UOSOJJJ4gx8jw==", "license": "MIT", "dependencies": { - "yocto-queue": "^1.1.1" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-roving-focus": "1.1.19", + "@radix-ui/react-separator": "1.1.15", + "@radix-ui/react-toggle-group": "1.1.19" }, - "engines": { - "node": ">=18" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/p-queue": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", - "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.16.tgz", + "integrity": "sha512-6EamKFRRnlpdadndbZ6LMwycfwkwPte1B42hs6QA0gYhjaOKqW4PZ4pjaW9UrlDX5eVt/OjncE7BFTPL5nmZhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.11" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.4.tgz", + "integrity": "sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.6.tgz", + "integrity": "sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==", "license": "MIT", "dependencies": { - "eventemitter3": "^5.0.1", - "p-timeout": "^6.1.2" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-layout-effect": "1.1.4" }, - "engines": { - "node": ">=18" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/p-timeout": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz", + "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==", "license": "MIT", - "engines": { - "node": ">=14.16" + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "license": "MIT" - }, - "node_modules/@treeseed/core/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz", + "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "engines": { - "node": ">=10" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz", + "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/undici": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.14.0.tgz", - "integrity": "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==", + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.4.tgz", + "integrity": "sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==", "license": "MIT", - "engines": { - "node": ">=20.18.1" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/vite": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", - "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz", + "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==", "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "@radix-ui/rect": "1.1.3" }, - "bin": { - "vite": "bin/vite.js" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.4.tgz", + "integrity": "sha512-D3anSY15EJoxrihpsXI6SMrmmonnQtR2ni7arO+Lfdg3O95b9hNXxONk8jA5C8ANdF/h5HMAxejgs8PWJ6rlhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.11.tgz", + "integrity": "sha512-NFS86RYYZb4/exihaESBGOpMJFz8MGLAfu3mOBSGByVnVPC9JPASfYubxd/8KbkQK0sYAv8lVQDEQukDX/qXvQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { + "@types/react": { "optional": true }, - "yaml": { + "@types/react-dom": { "optional": true } } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } + "node_modules/@radix-ui/rect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz", + "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==", + "license": "MIT" }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], + "node_modules/@reduxjs/toolkit": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", + "integrity": "sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "peer": true, + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.3.tgz", + "integrity": "sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==", "cpu": [ "arm64" ], @@ -8487,29 +5914,13 @@ "android" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.3.tgz", + "integrity": "sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==", "cpu": [ "arm64" ], @@ -8519,13 +5930,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.3.tgz", + "integrity": "sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==", "cpu": [ "x64" ], @@ -8535,29 +5946,13 @@ "darwin" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.3.tgz", + "integrity": "sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==", "cpu": [ "x64" ], @@ -8567,13 +5962,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.3.tgz", + "integrity": "sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==", "cpu": [ "arm" ], @@ -8583,13 +5978,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.3.tgz", + "integrity": "sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==", "cpu": [ "arm64" ], @@ -8599,31 +5994,15 @@ "linux" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.3.tgz", + "integrity": "sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==", "cpu": [ - "loong64" + "arm64" ], "license": "MIT", "optional": true, @@ -8631,15 +6010,15 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.3.tgz", + "integrity": "sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==", "cpu": [ - "mips64el" + "ppc64" ], "license": "MIT", "optional": true, @@ -8647,15 +6026,15 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.3.tgz", + "integrity": "sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==", "cpu": [ - "ppc64" + "s390x" ], "license": "MIT", "optional": true, @@ -8663,15 +6042,15 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.3.tgz", + "integrity": "sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==", "cpu": [ - "riscv64" + "x64" ], "license": "MIT", "optional": true, @@ -8679,15 +6058,15 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.3.tgz", + "integrity": "sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==", "cpu": [ - "s390x" + "x64" ], "license": "MIT", "optional": true, @@ -8695,445 +6074,546 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.3.tgz", + "integrity": "sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==", "cpu": [ - "x64" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "openharmony" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.3.tgz", + "integrity": "sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "netbsd" + "win32" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.3.tgz", + "integrity": "sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "netbsd" + "win32" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "node_modules/@rollup/pluginutils": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", + "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", "cpu": [ - "arm64" + "arm" ], "license": "MIT", "optional": true, "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } + "android" + ] }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", "cpu": [ - "x64" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } + "android" + ] }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } + "darwin" + ] }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } + "darwin" + ] }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "freebsd" + ] }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", "cpu": [ - "ia32" + "x64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "freebsd" + ] }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", "cpu": [ - "x64" + "arm" ], "license": "MIT", "optional": true, "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "linux" + ] }, - "node_modules/@treeseed/core/node_modules/vite/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "hasInstallScript": true, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/@treeseed/core/node_modules/workerd": { - "version": "1.20260114.0", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260114.0.tgz", - "integrity": "sha512-kTJ+jNdIllOzWuVA3NRQRvywP0T135zdCjAE2dAUY1BFbxM6fmMZV8BbskEoQ4hAODVQUfZQmyGctcwvVCKxFA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "bin": { - "workerd": "bin/workerd" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20260114.0", - "@cloudflare/workerd-darwin-arm64": "1.20260114.0", - "@cloudflare/workerd-linux-64": "1.20260114.0", - "@cloudflare/workerd-linux-arm64": "1.20260114.0", - "@cloudflare/workerd-windows-64": "1.20260114.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@treeseed/core/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@treeseed/core/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/@treeseed/sdk": { - "version": "0.12.62", - "resolved": "https://registry.npmjs.org/@treeseed/sdk/-/sdk-0.12.62.tgz", - "integrity": "sha512-wR5ukK2pqw0fUE9gJMYgJmIUlMTy4NoYKJrHEo6NAN/QFNrpru+9vilaS4kCPrcZQl/YAleuv962Z8c/pwwrBQ==", - "license": "AGPL-3.0-only", - "dependencies": { - "@github/copilot": "1.0.39", - "@github/copilot-language-server": "1.480.0", - "@github/copilot-sdk": "0.3.0", - "@remotion/bundler": "4.0.477", - "@remotion/renderer": "4.0.477", - "drizzle-orm": "^0.45.2", - "esbuild": "^0.28.0", - "extract-zip": "2.0.1", - "github-slugger": "^2.0.0", - "hono": "^4.8.2", - "ink": "^7.0.0", - "libsodium-wrappers": "^0.7.15", - "mdast-util-to-string": "^4.0.0", - "minisearch": "^7.2.0", - "octokit": "^5.0.3", - "pg": "^8.21.0", - "playwright": "^1.60.0", - "railway": "3.4.1", - "react": "^19.2.5", - "remark-mdx": "^3.1.1", - "remark-parse": "^11.0.0", - "remotion": "4.0.477", - "repomix": "^1.13.1", - "tar": "7.5.13", - "typescript": "^5.9.3", - "unified": "^11.0.5", - "wrangler": "4.86.0", - "yaml": "^2.8.1" - }, - "bin": { - "treeseed-sdk-verify": "dist/verification.js" - }, - "engines": { - "node": ">=22" - } - }, - "node_modules/@treeseed/sdk/node_modules/@cloudflare/kv-asset-handler": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.2.tgz", - "integrity": "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==", - "license": "MIT OR Apache-2.0", - "engines": { - "node": ">=18.0.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@treeseed/sdk/node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20260426.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260426.1.tgz", - "integrity": "sha512-Ch7DqsmYzSQRTY87pZpsGsFVz9VVBnLPnCBOHxKt1HH25a7oMu1w1PbPWqVmE0VerCLsj/TScX7Ob3v6E14TZw==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", "cpu": [ - "x64" + "arm64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "darwin" + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" ], - "engines": { - "node": ">=16" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@treeseed/sdk/node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20260426.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260426.1.tgz", - "integrity": "sha512-0m0U8vaPRH25SpKjbSyRql6gmPe4rCsETRV2WW0qBnuMdKNr5Vh5/Uez80xVrfiCCRMTULGeg63Nqg2vg6CDOA==", + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", "cpu": [ - "arm64" + "loong64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "darwin" + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" ], - "engines": { - "node": ">=16" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@treeseed/sdk/node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20260426.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260426.1.tgz", - "integrity": "sha512-C8LlC8uSYzg49y51n++75esxZmMp+Uz1OKHHA/4lkv6rjOTbcHQJuEwSLppjybVIXpv7A8MBhbu9iyCTvyv1mw==", + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", "cpu": [ - "x64" + "ppc64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" ], - "engines": { - "node": ">=16" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@treeseed/sdk/node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20260426.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260426.1.tgz", - "integrity": "sha512-ESVp/OIFMAqjQsa8BOP2BQQz5Vpfv6ncN6lNnIuNeOgsISQBdYk+LA60bwQHMud9tvmnSYtONp1zkZ8OQz+x6w==", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", "cpu": [ - "arm64" + "riscv64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" ], - "engines": { - "node": ">=16" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@treeseed/sdk/node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20260426.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260426.1.tgz", - "integrity": "sha512-d3Xj/IjINRgNVwH+eKhpUn4xkkcEewbWXbOvBlapiirKWh5zl9m0Epi3qOqmjyRYK6MICqIGXg4qZBEt0lxudw==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", "cpu": [ "x64" ], - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" ], - "engines": { - "node": ">=16" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", "cpu": [ - "ppc64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "aix" + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">=18" - } + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", "cpu": [ - "arm" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "android" + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" ], - "engines": { - "node": ">=18" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", "cpu": [ - "arm64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "android" + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz", + "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz", + "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", + "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "license": "MIT", "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.23", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.23.tgz", + "integrity": "sha512-iRoq6i6JDJP6Mt2A5JaPvzw0pgYHH6k92ij+yXiTrB7T2y9N789aWE3EHWj/5ztlJBokcCBja3iYLVdu5wgnkg==", + "license": "CC0-1.0" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT", + "peer": true + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", "cpu": [ - "x64" + "arm64" ], "license": "MIT", "optional": true, @@ -9141,13 +6621,13 @@ "android" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", "cpu": [ "arm64" ], @@ -9157,13 +6637,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", "cpu": [ "x64" ], @@ -9173,29 +6653,13 @@ "darwin" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", "cpu": [ "x64" ], @@ -9205,13 +6669,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", "cpu": [ "arm" ], @@ -9221,13 +6685,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", "cpu": [ "arm64" ], @@ -9237,47 +6701,15 @@ "linux" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", "cpu": [ - "mips64el" + "arm64" ], "license": "MIT", "optional": true, @@ -9285,15 +6717,15 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", "cpu": [ - "ppc64" + "x64" ], "license": "MIT", "optional": true, @@ -9301,15 +6733,15 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", "cpu": [ - "riscv64" + "x64" ], "license": "MIT", "optional": true, @@ -9317,141 +6749,102 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", "cpu": [ - "x64" + "wasm32" ], "license": "MIT", "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, "engines": { - "node": ">=18" + "node": ">=14.0.0" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", - "cpu": [ - "arm64" - ], + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "inBundle": true, "license": "MIT", "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", - "cpu": [ - "x64" - ], + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "inBundle": true, "license": "MIT", "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", - "cpu": [ - "arm64" - ], + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "inBundle": true, "license": "MIT", "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", - "cpu": [ - "x64" - ], + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "inBundle": true, "license": "MIT", "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", - "cpu": [ - "arm64" - ], + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "inBundle": true, "license": "MIT", "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "inBundle": true, + "license": "0BSD", + "optional": true }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", "cpu": [ "arm64" ], @@ -9461,15 +6854,15 @@ "win32" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", "cpu": [ - "ia32" + "x64" ], "license": "MIT", "optional": true, @@ -9477,180 +6870,109 @@ "win32" ], "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/@treeseed/sdk/node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", - "cpu": [ - "x64" - ], + "node_modules/@tailwindcss/vite": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz", + "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "tailwindcss": "4.3.3" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, - "node_modules/@treeseed/sdk/node_modules/miniflare": { - "version": "4.20260426.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260426.0.tgz", - "integrity": "sha512-KM+v76d04qT+NsPfVKVQEgnnuLNE3uzCCl2QKMTJ5OXor5JbBm1vpkQwQ+l7o5ELCrZ74RnyKhJKLiJyUA39Tw==", - "license": "MIT", + "node_modules/@treeseed/core": { + "version": "0.12.60-rc.6", + "resolved": "https://registry.npmjs.org/@treeseed/core/-/core-0.12.60-rc.6.tgz", + "integrity": "sha512-ITpD2oKTLg/V2wR6MbJoFaiGqApFMTo4FF85umDwtXLi6r8IGXq2wieClH7m+putK4+oPD0TcsqqLO3xBnlKow==", + "license": "Apache-2.0", "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "sharp": "^0.34.5", - "undici": "7.24.8", - "workerd": "1.20260426.1", - "ws": "8.18.0", - "youch": "4.1.0-beta.10" + "@astrojs/check": "^0.9.8", + "@astrojs/cloudflare": "^12.6.13", + "@astrojs/markdown-remark": "^6.3.11", + "@astrojs/mdx": "^4.3.14", + "@astrojs/node": "^9.4.3", + "@astrojs/react": "^4.4.2", + "@astrojs/sitemap": "3.7.0", + "@astrojs/starlight": "0.37.6", + "@tailwindcss/vite": "^4.1.4", + "@treeseed/sdk": ">=0.13.0-rc.39 <0.14.0", + "@treeseed/ui": ">=0.12.18-rc.1 <0.14.0", + "astro": "^5.6.1", + "esbuild": "^0.28.0", + "katex": "^0.16.22", + "nodemailer": "^8.0.4", + "rehype-katex": "^7.0.1", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.1", + "remark-math": "^6.0.0", + "remark-mdx": "^3.1.1", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "tailwindcss": "^4.1.4", + "typescript": "^5.9.3", + "unified": "^11.0.5", + "vitest": "^4.1.2", + "wrangler": "^4.80.0", + "yaml": "^2.8.1" }, "bin": { - "miniflare": "bootstrap.js" + "treeseed-workspace-bootstrap": "dist/scripts/treedx/workspaces/workspace-bootstrap.js" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@treeseed/sdk/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "license": "MIT" - }, - "node_modules/@treeseed/sdk/node_modules/undici": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz", - "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==", - "license": "MIT", - "engines": { - "node": ">=20.18.1" + "node": ">=22" } }, - "node_modules/@treeseed/sdk/node_modules/workerd": { - "version": "1.20260426.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260426.1.tgz", - "integrity": "sha512-ELvGgN8c9oo+E6EPyecxk1TEf6/eAK4TxxQTW5mQ87C7jbjCzhMbg0P2ije49UBHV0dkBYPJcJvcklUltipl2A==", - "hasInstallScript": true, + "node_modules/@treeseed/identity": { + "version": "0.1.0-rc.13", + "resolved": "https://registry.npmjs.org/@treeseed/identity/-/identity-0.1.0-rc.13.tgz", + "integrity": "sha512-41m+I+MiTJsA61f4EMiCfRm5AnCpLuaHCdrxfJ/lDApq36viveakwQoek5okMZSd4EreyOFG6FnzieoOGsWzdg==", "license": "Apache-2.0", - "bin": { - "workerd": "bin/workerd" + "dependencies": { + "@treeseed/sdk": "0.13.0-rc.107", + "jose": "6.2.12", + "oauth4webapi": "3.8.8" }, "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20260426.1", - "@cloudflare/workerd-darwin-arm64": "1.20260426.1", - "@cloudflare/workerd-linux-64": "1.20260426.1", - "@cloudflare/workerd-linux-arm64": "1.20260426.1", - "@cloudflare/workerd-windows-64": "1.20260426.1" + "node": ">=22.12.0" } }, - "node_modules/@treeseed/sdk/node_modules/wrangler": { - "version": "4.86.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.86.0.tgz", - "integrity": "sha512-9aa/gbF/HiUeeUEwyQpW5LDPBEzyt7iaE6xHwm0vk2Ly8A6J+jh03pzchqVnCCWR832mNyA28MD8oAYt0Kfvlw==", - "license": "MIT OR Apache-2.0", + "node_modules/@treeseed/sdk": { + "version": "0.13.0-rc.107", + "resolved": "https://registry.npmjs.org/@treeseed/sdk/-/sdk-0.13.0-rc.107.tgz", + "integrity": "sha512-860e/qNTEBTQeoW5CkdRIrPxvI64nvStKNq/BF/7BMOl3Z4KMsRbUtgeG2elY2QuDmXYOjjVE6kdcNVHU4D5ZA==", + "license": "Apache-2.0", "dependencies": { - "@cloudflare/kv-asset-handler": "0.4.2", - "@cloudflare/unenv-preset": "2.16.1", - "blake3-wasm": "2.1.5", - "esbuild": "0.27.3", - "miniflare": "4.20260426.0", - "path-to-regexp": "6.3.0", - "unenv": "2.0.0-rc.24", - "workerd": "1.20260426.1" - }, - "bin": { - "wrangler": "bin/wrangler.js", - "wrangler2": "bin/wrangler.js" + "@treeseed/treedx": "0.3.0-rc.17", + "esbuild": "^0.28.0", + "libsodium-wrappers-sumo": "0.8.4", + "typescript": "^5.9.3", + "yaml": "^2.8.1", + "zod": "^3.25.76" }, "engines": { - "node": ">=20.3.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@cloudflare/workers-types": "^4.20260426.1" - }, - "peerDependenciesMeta": { - "@cloudflare/workers-types": { - "optional": true - } + "node": ">=22" } }, - "node_modules/@treeseed/sdk/node_modules/wrangler/node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" - } - }, - "node_modules/@treeseed/sdk/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", + "node_modules/@treeseed/treedx": { + "version": "0.3.0-rc.17", + "resolved": "https://registry.npmjs.org/@treeseed/treedx/-/treedx-0.3.0-rc.17.tgz", + "integrity": "sha512-L1DCxkOZGS2of2IvbSC70baIpGlEuFBpHUhV4oKq53xXARN8dw4st2SFUz7IaxOIRzR9gD/vH12hIPnTFLJ7tA==", + "license": "Apache-2.0", "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "node": ">=22" } }, "node_modules/@treeseed/ui": { - "version": "0.12.17", - "resolved": "https://registry.npmjs.org/@treeseed/ui/-/ui-0.12.17.tgz", - "integrity": "sha512-dz+iNHu969vMmh7Cc+0z8O26inALrFGNGfZbc7hNeJ47fIIv2rOgO1nrRKJoDlqZz8GMnmN5d7N+vjab7GPBUw==", + "version": "0.12.18-rc.20", + "resolved": "https://registry.npmjs.org/@treeseed/ui/-/ui-0.12.18-rc.20.tgz", + "integrity": "sha512-zrioS5i7r7iE4WXvTVAGGQyIZa3iKr81CJvrc8JyZaHtqF/YEUycy2YgPva0pTBTKgtSdmuoYU9W0pPS028Rzw==", "license": "Apache-2.0", "dependencies": { "@codemirror/lang-markdown": "^6.5.0", @@ -9663,6 +6985,7 @@ "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", + "string-width": "^8.2.2", "unified": "^11.0.5", "yaml": "^2.8.1" }, @@ -9671,27 +6994,12 @@ }, "peerDependencies": { "astro": "^5.0.0 || ^6.0.0", + "ink": "^7.1.1", "react": "^18.3.0 || ^19.0.0", "react-dom": "^18.3.0 || ^19.0.0", "recharts": "^3.0.0" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", - "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/aws-lambda": { - "version": "8.10.162", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.162.tgz", - "integrity": "sha512-Fn658grtLOci1oxi1391vvDWJRKNGWRSqfxRkmN/Iy3c0tQH1USMKEXcPYHLvope+ZgTFocx9FRQJx1muBL6qw==", - "license": "MIT" - }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -9792,9 +7100,9 @@ } }, "node_modules/@types/d3-shape": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", - "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==", "license": "MIT", "peer": true, "dependencies": { @@ -9830,41 +7138,6 @@ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "license": "MIT" }, - "node_modules/@types/dom-mediacapture-transform": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@types/dom-mediacapture-transform/-/dom-mediacapture-transform-0.1.12.tgz", - "integrity": "sha512-d7/QsLRwF864A5mgIM/YrfiglHoYn7zgCcAoJgW404r+2DwnNr7EBbLnCWpmOMgH8y0te73L1AV6H1bmauaWFw==", - "license": "MIT", - "dependencies": { - "@types/dom-webcodecs": "*" - } - }, - "node_modules/@types/dom-webcodecs": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", - "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==", - "license": "MIT" - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -9895,12 +7168,6 @@ "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", "license": "MIT" }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, "node_modules/@types/katex": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", @@ -9946,25 +7213,19 @@ "undici-types": "~7.18.0" } }, - "node_modules/@types/parse-path": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz", - "integrity": "sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==", - "license": "MIT" - }, "node_modules/@types/react": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", - "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", + "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", "license": "MIT", "dependencies": { "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==", "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -9979,6 +7240,12 @@ "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -9992,16 +7259,6 @@ "license": "MIT", "peer": true }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@ungap/structured-clone": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", @@ -10219,609 +7476,893 @@ "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", "license": "MIT" }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-i18n": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-4.2.0.tgz", + "integrity": "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==", + "license": "MIT", + "peerDependencies": { + "ajv": "^8.0.0-beta.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", + "peer": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", "license": "MIT" }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" + "engines": { + "node": ">=12" } }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "node_modules/astro": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.18.2.tgz", + "integrity": "sha512-TnFwLnAXty5MXKPDGuKXqK4AMBXG+FH6RUdK7Oyc3gyfNoFIthT+4eRbzOK43bdRlLaZuxgciDSjgtggZ3OtGQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.6", + "@astrojs/markdown-remark": "6.3.11", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^4.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.1.1", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.6.2", + "diff": "^8.0.3", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.27.3", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.4.0", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "svgo": "^4.0.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.3", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.4", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" } }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "node_modules/astro-expressive-code": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.41.7.tgz", + "integrity": "sha512-hUpogGc6DdAd+I7pPXsctyYPRBJDK7Q7d06s4cyP0Vz3OcbziP3FNzN0jZci1BpCvLn9675DvS7B9ctKKX64JQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" + "rehype-expressive-code": "^0.41.7" + }, + "peerDependencies": { + "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" } }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "node_modules/astro/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "node_modules/astro/node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "node_modules/astro/node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "node_modules/astro/node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">= 0.6" + "node": ">=18" } }, - "node_modules/acorn": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", - "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "node_modules/astro/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.4.0" + "node": ">=18" } }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "node_modules/astro/node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" + "node": ">=18" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/astro/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "node_modules/astro/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "node_modules/astro/node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], "license": "MIT", - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/astro/node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ajv-i18n": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-4.2.0.tgz", - "integrity": "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==", + "node_modules/astro/node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], "license": "MIT", - "peerDependencies": { - "ajv": "^8.0.0-beta.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "node_modules/astro/node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" + "node_modules/astro/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/astro/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/astro/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/astro/node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/astro/node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/ansi-escapes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "node_modules/astro/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "environment": "^1.0.0" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "node_modules/astro/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=18" } }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/astro/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=18" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, + "node_modules/astro/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "node_modules/astro/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=18" } }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/aria-hidden": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", - "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "node_modules/astro/node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "license": "Apache-2.0", + "node_modules/astro/node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "node_modules/array-iterate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "node_modules/astro/node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "node_modules/astro/node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", - "license": "MIT", - "bin": { - "astring": "bin/astring" - } + "node_modules/astro/node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" }, - "node_modules/astro": { - "version": "6.4.8", - "resolved": "https://registry.npmjs.org/astro/-/astro-6.4.8.tgz", - "integrity": "sha512-KK5lX90uU9EeVaTjINyj3sy9/NFXVa59aowaqbWBDDKLXZh4rr7GwIaCFYVetE22MJtsCNFerQXn0vlCLmpP/Q==", + "node_modules/astro/node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "@astrojs/compiler": "^4.0.0", - "@astrojs/internal-helpers": "0.10.0", - "@astrojs/markdown-remark": "7.2.0", - "@astrojs/telemetry": "3.3.2", - "@capsizecss/unpack": "^4.0.0", - "@clack/prompts": "^1.1.0", - "@oslojs/encoding": "^1.1.0", - "@rollup/pluginutils": "^5.3.0", - "aria-query": "^5.3.2", - "axobject-query": "^4.1.0", - "ci-info": "^4.4.0", - "clsx": "^2.1.1", - "common-ancestor-path": "^2.0.0", - "cookie": "^1.1.1", - "devalue": "^5.8.1", - "diff": "^8.0.3", - "dset": "^3.1.4", - "es-module-lexer": "^2.0.0", - "esbuild": "^0.27.3", - "flattie": "^1.1.1", - "fontace": "~0.4.1", - "get-tsconfig": "5.0.0-beta.4", - "github-slugger": "^2.0.0", - "html-escaper": "3.0.3", - "http-cache-semantics": "^4.2.0", - "js-yaml": "^4.1.1", - "jsonc-parser": "^3.3.1", - "magic-string": "^0.30.21", - "magicast": "^0.5.2", - "mrmime": "^2.0.1", - "neotraverse": "^0.6.18", - "obug": "^2.1.1", - "p-limit": "^7.3.0", - "p-queue": "^9.1.0", - "package-manager-detector": "^1.6.0", - "piccolore": "^0.1.3", - "picomatch": "^4.0.4", - "rehype": "^13.0.2", - "semver": "^7.7.4", - "shiki": "^4.0.2", - "smol-toml": "^1.6.0", - "svgo": "^4.0.1", - "tinyclip": "^0.1.12", - "tinyexec": "^1.0.4", - "tinyglobby": "^0.2.15", - "ultrahtml": "^1.6.0", - "unifont": "~0.7.4", - "unist-util-visit": "^5.1.0", - "unstorage": "^1.17.5", - "vfile": "^6.0.3", - "vite": "^7.3.2", - "vitefu": "^1.1.2", - "xxhash-wasm": "^1.1.0", - "yargs-parser": "^22.0.0", - "zod": "^4.3.6" + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/astro/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/astro/node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { - "astro": "bin/astro.mjs" + "vite": "bin/vite.js" }, "engines": { - "node": ">=22.12.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/astrodotbuild" + "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "sharp": "^0.34.0" - } - }, - "node_modules/astro-expressive-code": { - "version": "0.41.7", - "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.41.7.tgz", - "integrity": "sha512-hUpogGc6DdAd+I7pPXsctyYPRBJDK7Q7d06s4cyP0Vz3OcbziP3FNzN0jZci1BpCvLn9675DvS7B9ctKKX64JQ==", - "license": "MIT", - "dependencies": { - "rehype-expressive-code": "^0.41.7" + "fsevents": "~2.3.3" }, "peerDependencies": { - "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" - } - }, - "node_modules/astro/node_modules/@astrojs/compiler": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-4.0.0.tgz", - "integrity": "sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==", - "license": "MIT" - }, - "node_modules/astro/node_modules/@astrojs/internal-helpers": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.10.0.tgz", - "integrity": "sha512-Ry2R3VPeIN4uPCSA4xQc+e+vsJXkalKpEbDc07hV+a/o5Bs2N/s/uDcPJH/05L19DKh9tAy7e6JM3YZ6Cxfezw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.4", - "@types/mdast": "^4.0.4", - "js-yaml": "^4.1.1", - "picomatch": "^4.0.4", - "retext-smartypants": "^6.2.0", - "shiki": "^4.0.2", - "smol-toml": "^1.6.0", - "unified": "^11.0.5" - } - }, - "node_modules/astro/node_modules/@astrojs/markdown-remark": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-7.2.0.tgz", - "integrity": "sha512-+YxmVQu1Bd+MFfSzjq1rOJvD9+nIOJzz5YIIhdIH01RrxRkKbyKoEgyIqP3yv51MhzMDgd79QaPv+kCVPT8vHw==", - "license": "MIT", - "dependencies": { - "@astrojs/internal-helpers": "0.10.0", - "@astrojs/prism": "4.0.2", - "github-slugger": "^2.0.0", - "hast-util-from-html": "^2.0.3", - "hast-util-to-text": "^4.0.2", - "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^7.0.0", - "rehype-stringify": "^10.0.1", - "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.2", - "remark-smartypants": "^3.0.2", - "unified": "^11.0.5", - "unist-util-remove-position": "^5.0.0", - "unist-util-visit": "^5.1.0", - "unist-util-visit-parents": "^6.0.2", - "vfile": "^6.0.3" - } - }, - "node_modules/astro/node_modules/@astrojs/prism": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-4.0.2.tgz", - "integrity": "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==", - "license": "MIT", - "dependencies": { - "prismjs": "^1.30.0" + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, - "engines": { - "node": ">=22.12.0" + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/astro/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", "cpu": [ "ppc64" ], @@ -10834,10 +8375,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", "cpu": [ "arm" ], @@ -10850,10 +8391,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", "cpu": [ "arm64" ], @@ -10866,10 +8407,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", "cpu": [ "x64" ], @@ -10882,10 +8423,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], @@ -10898,10 +8439,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", "cpu": [ "x64" ], @@ -10914,10 +8455,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", "cpu": [ "arm64" ], @@ -10930,10 +8471,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", "cpu": [ "x64" ], @@ -10946,10 +8487,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", "cpu": [ "arm" ], @@ -10962,10 +8503,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", "cpu": [ "arm64" ], @@ -10978,10 +8519,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", "cpu": [ "ia32" ], @@ -10994,10 +8535,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", "cpu": [ "loong64" ], @@ -11010,10 +8551,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", "cpu": [ "mips64el" ], @@ -11026,10 +8567,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", "cpu": [ "ppc64" ], @@ -11042,10 +8583,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", "cpu": [ "riscv64" ], @@ -11058,10 +8599,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "cpu": [ "s390x" ], @@ -11074,10 +8615,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ "x64" ], @@ -11090,10 +8631,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ "arm64" ], @@ -11105,11 +8646,11 @@ "engines": { "node": ">=18" } - }, - "node_modules/astro/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ "x64" ], @@ -11122,10 +8663,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], @@ -11138,10 +8679,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], @@ -11154,10 +8695,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "cpu": [ "arm64" ], @@ -11170,10 +8711,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], @@ -11186,10 +8727,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], @@ -11202,10 +8743,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ "ia32" ], @@ -11218,10 +8759,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "node_modules/astro/node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ "x64" ], @@ -11234,90 +8775,10 @@ "node": ">=18" } }, - "node_modules/astro/node_modules/@shikijs/core": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.3.1.tgz", - "integrity": "sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA==", - "license": "MIT", - "dependencies": { - "@shikijs/primitive": "4.3.1", - "@shikijs/types": "4.3.1", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.5" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/astro/node_modules/@shikijs/engine-javascript": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.3.1.tgz", - "integrity": "sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.3.1", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.6" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/astro/node_modules/@shikijs/engine-oniguruma": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.3.1.tgz", - "integrity": "sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.3.1", - "@shikijs/vscode-textmate": "^10.0.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/astro/node_modules/@shikijs/langs": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.3.1.tgz", - "integrity": "sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.3.1" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/astro/node_modules/@shikijs/themes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.3.1.tgz", - "integrity": "sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.3.1" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/astro/node_modules/@shikijs/types": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.3.1.tgz", - "integrity": "sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g==", - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/astro/node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "node_modules/astro/node_modules/vite/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -11327,160 +8788,41 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" - } - }, - "node_modules/astro/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/astro/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/astro/node_modules/shiki": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.3.1.tgz", - "integrity": "sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw==", - "license": "MIT", - "dependencies": { - "@shikijs/core": "4.3.1", - "@shikijs/engine-javascript": "4.3.1", - "@shikijs/engine-oniguruma": "4.3.1", - "@shikijs/langs": "4.3.1", - "@shikijs/themes": "4.3.1", - "@shikijs/types": "4.3.1", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/astro/node_modules/vite": { - "version": "7.3.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", - "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.27.0 || ^0.28.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, - "node_modules/astro/node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" + "node_modules/astro/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" } }, "node_modules/auto-bind": { @@ -11488,6 +8830,7 @@ "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", "license": "MIT", + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -11514,15 +8857,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/base-64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", @@ -11530,9 +8864,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.43", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", - "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", + "version": "2.11.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.12.tgz", + "integrity": "sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -11566,72 +8900,18 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/before-after-hook": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", - "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", - "license": "Apache-2.0" - }, - "node_modules/binary-extensions": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-3.1.0.tgz", - "integrity": "sha512-Jvvd9hy1w+xUad8+ckQsWA/V1AoyubOvqn0aygjMOVM4BfIaRav1NFS3LsTSDaV4n4FtcCtQXvzep1E6MboqwQ==", - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/blake3-wasm": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", "license": "MIT" }, - "node_modules/body-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", - "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", - "license": "MIT", - "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" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "license": "ISC" }, - "node_modules/bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "license": "MIT" - }, - "node_modules/boundary": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/boundary/-/boundary-2.0.0.tgz", - "integrity": "sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==", - "license": "BSD-2-Clause" - }, "node_modules/boxen": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", @@ -11733,34 +9013,10 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browserslist": { - "version": "4.28.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", - "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "funding": [ { "type": "opencollective", @@ -11777,9 +9033,9 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.42", - "caniuse-lite": "^1.0.30001803", - "electron-to-chromium": "^1.5.389", + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, @@ -11790,59 +9046,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/camelcase": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", @@ -11856,9 +9059,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001805", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz", - "integrity": "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA==", + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", "funding": [ { "type": "opencollective", @@ -11961,24 +9164,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, "node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -12005,6 +9190,7 @@ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-4.0.1.tgz", "integrity": "sha512-5IOn+jcCEHEraYolBPs/sT4BxYCe2nHg374OPiItB1O96KZFseS2gthU4twyYzeDcFew4DaUM/xwc5BQf08JJw==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.20 <19 || >=20.10" }, @@ -12017,6 +9203,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "license": "MIT", + "peer": true, "dependencies": { "restore-cursor": "^4.0.0" }, @@ -12032,6 +9219,7 @@ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-6.1.1.tgz", "integrity": "sha512-06p9vyLahLa4zkGcgsGxU6iEkSOiuI4fhCH6Emhe2lPAcoUv73n72DnODsnHA+5wwXGnV0n9M9/qOQJSjYhFhw==", "license": "MIT", + "peer": true, "dependencies": { "slice-ansi": "^9.0.0", "string-width": "^8.2.0" @@ -12044,90 +9232,54 @@ } }, "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=20" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" }, "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" + "node": ">=18" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -12159,6 +9311,7 @@ "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", "license": "MIT", + "peer": true, "dependencies": { "convert-to-spaces": "^2.0.1" }, @@ -12191,24 +9344,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -12229,13 +9364,10 @@ } }, "node_modules/common-ancestor-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz", - "integrity": "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">= 18" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" }, "node_modules/compute-scroll-into-view": { "version": "2.0.4", @@ -12243,32 +9375,6 @@ "integrity": "sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g==", "license": "MIT" }, - "node_modules/content-disposition": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", - "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/content-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", - "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -12280,6 +9386,7 @@ "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", "license": "MIT", + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } @@ -12303,51 +9410,11 @@ "integrity": "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==", "license": "MIT" }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/crelt": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.7.tgz", - "integrity": "sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.7.tgz", + "integrity": "sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==", + "license": "MIT" }, "node_modules/crossws": { "version": "0.3.5", @@ -12358,53 +9425,6 @@ "uncrypto": "^0.1.3" } }, - "node_modules/css-loader": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.4.tgz", - "integrity": "sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.40", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.6.3" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", - "webpack": "^5.27.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-loader/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -12682,24 +9702,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/defu": { "version": "6.1.7", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", @@ -12758,9 +9760,9 @@ } }, "node_modules/devalue": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.1.tgz", - "integrity": "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.0.tgz", + "integrity": "sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==", "license": "MIT" }, "node_modules/devlop": { @@ -12881,131 +9883,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "license": "MIT" }, - "node_modules/drizzle-orm": { - "version": "0.45.2", - "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.2.tgz", - "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", - "license": "Apache-2.0", - "peerDependencies": { - "@aws-sdk/client-rds-data": ">=3", - "@cloudflare/workers-types": ">=4", - "@electric-sql/pglite": ">=0.2.0", - "@libsql/client": ">=0.10.0", - "@libsql/client-wasm": ">=0.10.0", - "@neondatabase/serverless": ">=0.10.0", - "@op-engineering/op-sqlite": ">=2", - "@opentelemetry/api": "^1.4.1", - "@planetscale/database": ">=1.13", - "@prisma/client": "*", - "@tidbcloud/serverless": "*", - "@types/better-sqlite3": "*", - "@types/pg": "*", - "@types/sql.js": "*", - "@upstash/redis": ">=1.34.7", - "@vercel/postgres": ">=0.8.0", - "@xata.io/client": "*", - "better-sqlite3": ">=7", - "bun-types": "*", - "expo-sqlite": ">=14.0.0", - "gel": ">=2", - "knex": "*", - "kysely": "*", - "mysql2": ">=2", - "pg": ">=8", - "postgres": ">=3", - "sql.js": ">=1", - "sqlite3": ">=5" - }, - "peerDependenciesMeta": { - "@aws-sdk/client-rds-data": { - "optional": true - }, - "@cloudflare/workers-types": { - "optional": true - }, - "@electric-sql/pglite": { - "optional": true - }, - "@libsql/client": { - "optional": true - }, - "@libsql/client-wasm": { - "optional": true - }, - "@neondatabase/serverless": { - "optional": true - }, - "@op-engineering/op-sqlite": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@planetscale/database": { - "optional": true - }, - "@prisma/client": { - "optional": true - }, - "@tidbcloud/serverless": { - "optional": true - }, - "@types/better-sqlite3": { - "optional": true - }, - "@types/pg": { - "optional": true - }, - "@types/sql.js": { - "optional": true - }, - "@upstash/redis": { - "optional": true - }, - "@vercel/postgres": { - "optional": true - }, - "@xata.io/client": { - "optional": true - }, - "better-sqlite3": { - "optional": true - }, - "bun-types": { - "optional": true - }, - "expo-sqlite": { - "optional": true - }, - "gel": { - "optional": true - }, - "knex": { - "optional": true - }, - "kysely": { - "optional": true - }, - "mysql2": { - "optional": true - }, - "pg": { - "optional": true - }, - "postgres": { - "optional": true - }, - "prisma": { - "optional": true - }, - "sql.js": { - "optional": true - }, - "sqlite3": { - "optional": true - } - } - }, "node_modules/dset": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", @@ -13015,20 +9892,6 @@ "node": ">=4" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -13036,9 +9899,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.389", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz", - "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==", + "version": "1.5.402", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.402.tgz", + "integrity": "sha512-/oOpMaPT6Yg+6/1XQhyIPlzgj7Ye9zf+nNM2Uh6OcE2G2oNptWazFa+qB2Pdqqbsc9KnIDzgAntoYN0dbwOXwA==", "license": "ISC" }, "node_modules/emmet": { @@ -13072,19 +9935,10 @@ "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/enhanced-resolve": { - "version": "5.21.6", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", - "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==", + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -13111,6 +9965,7 @@ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -13118,15 +9973,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "license": "MIT", - "dependencies": { - "stackframe": "^1.3.4" - } - }, "node_modules/error-stack-parser-es": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", @@ -13136,50 +9982,23 @@ "url": "https://github.com/sponsors/antfu" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/es-module-lexer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.0.tgz", - "integrity": "sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", "license": "MIT" }, - "node_modules/es-object-atoms": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", - "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/es-toolkit": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.49.0.tgz", - "integrity": "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.51.0.tgz", + "integrity": "sha512-zC2lQGkM7QX+Gm6iM3+WIdZJzthsEd14LvRNJneSO2hzyz/zNBENR8+YXWo1cKxgPBtV6ksPYHELbcwBRzmdCw==", "license": "MIT", + "peer": true, "workspaces": [ "docs", - "benchmarks" + "benchmarks", + "tests/types", + "tests/browser-compat" ] }, "node_modules/esast-util-from-estree": { @@ -13282,49 +10101,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/estree-util-attach-comments": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", @@ -13402,15 +10178,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/estree-util-to-js/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, "node_modules/estree-util-visit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", @@ -13444,147 +10211,15 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz", - "integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/expect-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", - "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", - "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", - "license": "MIT", - "dependencies": { - "ip-address": "^10.2.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" - } - }, - "node_modules/express/node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } + "license": "MIT" }, - "node_modules/express/node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "license": "Apache-2.0", "engines": { - "node": ">= 0.6" + "node": ">=12.0.0" } }, "node_modules/expressive-code": { @@ -13605,82 +10240,16 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-string-truncated-width": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", - "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", - "license": "MIT" - }, - "node_modules/fast-string-width": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", - "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", - "license": "MIT", - "dependencies": { - "fast-string-truncated-width": "^3.0.2" - } - }, "node_modules/fast-uri": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", - "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", "funding": [ { "type": "github", @@ -13693,40 +10262,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fast-wrap-ansi": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", - "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", - "license": "MIT", - "dependencies": { - "fast-string-width": "^3.0.2" - } - }, - "node_modules/fast-xml-builder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.3.0.tgz", - "integrity": "sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "path-expression-matcher": "^1.6.2", - "xml-naming": "^0.3.0" - } - }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fault": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", @@ -13740,15 +10275,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -13766,39 +10292,6 @@ } } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/flattie": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", @@ -13837,15 +10330,6 @@ "node": ">=0.4.x" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -13855,16 +10339,10 @@ "node": ">= 0.8" } }, - "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "license": "Unlicense" - }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -13875,15 +10353,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -13914,30 +10383,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-nonce": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", @@ -13947,142 +10392,18 @@ "node": ">=6" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-tsconfig": { - "version": "5.0.0-beta.4", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz", - "integrity": "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==", - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "engines": { - "node": ">=20.20.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/git-up": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-8.1.1.tgz", - "integrity": "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==", - "license": "MIT", - "dependencies": { - "is-ssh": "^1.4.0", - "parse-url": "^9.2.0" - } - }, - "node_modules/git-url-parse": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-16.1.0.tgz", - "integrity": "sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==", - "license": "MIT", - "dependencies": { - "git-up": "^8.1.0" - } - }, "node_modules/github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", "license": "ISC" }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/globby": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.1.tgz", - "integrity": "sha512-JmsqJalahxxgW8V2ecSQ2G7UjPlI9cpKdrkG9KoNiXhd/YslXOTEB0cViENWUznuovIuNT+FkMbraDGjr4FCUg==", - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.5", - "is-path-inside": "^4.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.4.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gpt-tokenizer": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-3.4.0.tgz", - "integrity": "sha512-wxFLnhIXTDjYebd9A9pGl3e31ZpSypbpIJSOswbgop5jLte/AsZVDvjlbEuVFlsqZixVKqbcoNmRlFDf6pz/UQ==", - "license": "MIT" - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphql": { - "version": "16.14.2", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.14.2.tgz", - "integrity": "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==", - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" - } - }, "node_modules/h3": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.11.tgz", @@ -14100,69 +10421,6 @@ "uncrypto": "^0.1.3" } }, - "node_modules/handlebars": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", - "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/hast-util-embedded": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", @@ -14559,52 +10817,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hono": { - "version": "4.12.30", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.30.tgz", - "integrity": "sha512-emn+JoJjrN9YTpRDS5it/UI2SO9BAE37T6I3d963RxcZ81G9A4pr2SZTEiiaiKbzx+NKRg5BZ89fCL7gCJCUog==", - "license": "MIT", - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "node_modules/html-escaper": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", - "license": "MIT" - }, - "node_modules/html-to-text": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", - "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", - "license": "MIT", - "dependencies": { - "@selderee/plugin-htmlparser2": "^0.11.0", - "deepmerge": "^4.3.1", - "dom-serializer": "^2.0.0", - "htmlparser2": "^8.0.2", - "selderee": "^0.11.0" - }, - "engines": { - "node": ">=14" - } + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" }, "node_modules/html-void-elements": { "version": "3.0.0", @@ -14626,31 +10843,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/html5parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html5parser/-/html5parser-3.0.0.tgz", - "integrity": "sha512-iNpSopa+4YHX50UOk825tBy7MghmXHo/ZpLskBYN0kAr1xhH8GlIMk5bLRXcZlfP3AnLUcSuFMu8C4MdOUxA8A==", - "license": "MIT" - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", @@ -14677,15 +10869,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, "node_modules/i18next": { "version": "23.16.8", "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz", @@ -14709,47 +10892,10 @@ "@babel/runtime": "^7.23.2" } }, - "node_modules/iconv-lite": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", - "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/ignore": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", - "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/immer": { - "version": "11.1.11", - "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.11.tgz", - "integrity": "sha512-qzXuyXAkPySAGYkfsAwodDPWT8Zm7/Uo5BNt4BjhMhG5WlWyZZ4wQqnWwdS8kjlQ1Cwu6gjw3A6+0gTQwlyYtw==", + "version": "11.1.18", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.18.tgz", + "integrity": "sha512-EQyQtLiYW029lyoczMl/Hh4Xu7cDecSc58JRYpHyL4tIAu3eqd1yJzQX04d2BZHDkzFFvm6qJEJWOtfDSWAXbQ==", "license": "MIT", "peer": true, "funding": { @@ -14772,6 +10918,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -14786,10 +10933,11 @@ "license": "ISC" }, "node_modules/ink": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/ink/-/ink-7.1.0.tgz", - "integrity": "sha512-VWE6/yeLtFCJBNLflyI2OSylyXK1Rc24LuXup8Qt+icwkmmycFNdbn8IkSp6Frc0h1iA0NOvvi1ajW44U/w3Qg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ink/-/ink-7.1.1.tgz", + "integrity": "sha512-Y43xxa1ZSPvpmfLHcN5o+OdP8Rf8ykkNJEuKYOUNZKT8wXVNLFTtEm1nSDMQkfBH+YANF4Xuu0hhZ4ejqAtN2w==", "license": "MIT", + "peer": true, "dependencies": { "@alcalzone/ansi-tokenize": "^0.3.0", "ansi-escapes": "^7.3.0", @@ -14850,24 +10998,6 @@ "node": ">=12" } }, - "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/iron-webcrypto": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", @@ -14901,21 +11031,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-binary-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-3.0.0.tgz", - "integrity": "sha512-eSkpSYbqKip82Uw4z0iBK/5KmVzL2pf36kNKRtu6+mKvrow9sqF4w5hocQ9yV5v+9+wzHt620x3B7Wws/8lsGg==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^3.0.0" - }, - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-decimal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", @@ -14927,34 +11042,26 @@ } }, "node_modules/is-docker": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-4.0.0.tgz", - "integrity": "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "license": "MIT", "bin": { "is-docker": "cli.js" }, "engines": { - "node": ">=20" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "license": "MIT", + "peer": true, "dependencies": { "get-east-asian-width": "^1.3.1" }, @@ -14965,18 +11072,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-hexadecimal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", @@ -14992,6 +11087,7 @@ "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz", "integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==", "license": "MIT", + "peer": true, "bin": { "is-in-ci": "cli.js" }, @@ -15020,42 +11116,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-inside-container/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", - "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -15068,33 +11128,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "node_modules/is-ssh": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", - "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", - "license": "MIT", - "dependencies": { - "protocols": "^2.0.1" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-wsl": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", @@ -15110,24 +11143,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isbinaryfile": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", - "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==", - "license": "MIT", - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, "node_modules/isomorphic.js": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", @@ -15139,20 +11154,6 @@ "url": "https://github.com/sponsors/dmonad" } }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", @@ -15163,9 +11164,9 @@ } }, "node_modules/jose": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", - "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "version": "6.2.12", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", + "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -15178,9 +11179,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "funding": [ { "type": "github", @@ -15199,15 +11200,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jschardet": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-3.1.4.tgz", - "integrity": "sha512-/kmVISmrwVwtyYU40iQUOp3SUPk2dhNCMsZBQX0R1/jZ8maaXJ/oZIzUOiyOqcgtLnETFKYChbJ5iDC/eWmFHg==", - "license": "LGPL-2.1+", - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -15220,30 +11212,12 @@ "node": ">=6" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause" - }, - "node_modules/json-with-bigint": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.10.tgz", - "integrity": "sha512-Vcx+JVNEBts/xfcoCS69sKrOhOk/3TVlvlT+XzUOefVKnnrbYSCKpDCm10pohsJFtsJVYnwa/cXRZ4eElzaM6w==", - "license": "MIT" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -15296,21 +11270,23 @@ "node": ">= 8" } }, - "node_modules/leac": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", - "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==", + "node_modules/lexical": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.48.0.tgz", + "integrity": "sha512-KK4Tyr/cPsleoZ7XvhGRiRmcrZidSmoFUdIXK9nPubIifoC+80Dc5THyc4xtGKtsW24S1TsHzk5gmfBU+TxmEg==", "license": "MIT", - "funding": { - "url": "https://ko-fi.com/killymxi" + "dependencies": { + "@lexical/internal": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/lexical": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.35.0.tgz", - "integrity": "sha512-3VuV8xXhh5xJA6tzvfDvE0YBCMkIZUmxtRilJQDDdCgJCc+eut6qAv2qbN+pbqvarqcQqPN1UF+8YvsjmyOZpw==", - "license": "MIT" - }, "node_modules/lib0": { "version": "0.2.117", "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.117.tgz", @@ -15333,34 +11309,17 @@ "url": "https://github.com/sponsors/dmonad" } }, - "node_modules/libsodium": { - "version": "0.7.16", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.16.tgz", - "integrity": "sha512-3HrzSPuzm6Yt9aTYCDxYEG8x8/6C0+ag655Y7rhhWZM9PT4NpdnbqlzXhGZlDnkgR6MeSTnOt/VIyHLs9aSf+Q==", - "license": "ISC" - }, "node_modules/libsodium-sumo": { - "version": "0.7.16", - "resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.16.tgz", - "integrity": "sha512-x6atrz2AdXCJg6G709x9W9TTJRI6/0NcL5dD0l5GGVqNE48UJmDsjO4RUWYTeyXXUpg+NXZ2SHECaZnFRYzwGA==", - "license": "ISC" - }, - "node_modules/libsodium-wrappers": { - "version": "0.7.16", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.16.tgz", - "integrity": "sha512-Gtr/WBx4dKjvRL1pvfwZqu7gO6AfrQ0u9vFL+kXihtHf6NfkROR8pjYWn98MFDI3jN19Ii1ZUfPR9afGiPyfHg==", - "license": "ISC", - "dependencies": { - "libsodium": "^0.7.16" - } + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.8.4.tgz", + "integrity": "sha512-TMtHShQfVVsaxDygyapvUC3o7YsPgXa/hRWeIgzyFz6w5k/1hirGptCxp1U7XwW3rCskaTTYKgV10v86UiGgNw==" }, "node_modules/libsodium-wrappers-sumo": { - "version": "0.7.16", - "resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.16.tgz", - "integrity": "sha512-gR0JEFPeN3831lB9+ogooQk0KH4K5LSMIO5Prd5Q5XYR2wHFtZfPg0eP7t1oJIWq+UIzlU4WVeBxZ97mt28tXw==", - "license": "ISC", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.8.4.tgz", + "integrity": "sha512-ql7hcgulKZ3ekfa2DGAogcCKsWU0diA/0nArz1CFzh93WQdb46/Kj18ka/Hifq6uA3Ush34Pc6vU/6HXeRwUkg==", "dependencies": { - "libsodium-sumo": "^0.7.16" + "libsodium-sumo": "^0.8.0" } }, "node_modules/lightningcss": { @@ -15499,9 +11458,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -15522,9 +11478,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -15545,9 +11498,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -15568,9 +11518,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -15624,25 +11571,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/loader-runner": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", - "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", - "license": "MIT", - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", - "license": "MIT" - }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -15665,18 +11593,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -15687,13 +11603,13 @@ } }, "node_modules/magicast": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", - "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.4.tgz", + "integrity": "sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.3", - "@babel/types": "^7.29.0", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", "source-map-js": "^1.2.1" } }, @@ -15719,15 +11635,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/mdast-util-definitions": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", @@ -16085,89 +11992,23 @@ } }, "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.27.1", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", - "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", - "license": "CC0-1.0" - }, - "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/mediabunny": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.45.0.tgz", - "integrity": "sha512-oK3sMMYbucoF6LUX62L/2M9d+p9ve6KDQgL87kNfhsB0/XmTe9iRLUcgQgg9Gpgvi8Sb96zYfOUL6i17y0bdNg==", - "license": "MPL-2.0", - "workspaces": [ - ".", - "packages/*" - ], - "dependencies": { - "@types/dom-mediacapture-transform": "^0.1.11", - "@types/dom-webcodecs": "0.1.13" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/Vanilagy" - } - }, - "node_modules/memfs": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.3.tgz", - "integrity": "sha512-eivjfi7Ahr6eQTn44nvTnR60e4a1Fs1Via2kCR5lHo/kyNoiMWaXCNJ/GpSd0ilXas2JSOl9B5FTIhflXu0hlg==", - "license": "Unlicense", - "dependencies": { - "fs-monkey": "1.0.3" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "@types/mdast": "^4.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "license": "CC0-1.0" }, "node_modules/micromark": { "version": "4.0.2", @@ -16954,155 +12795,537 @@ ], "license": "MIT" }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/miniflare": { + "version": "5.20260825.0-alpha", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-5.20260825.0-alpha.tgz", + "integrity": "sha512-ZwlF6LuX43ilx9EwMRDKHenoGXiNdcKSyGx5aPaJhuozujVZasb2lRR7t3ojJZSnVzwDPsBBYCu8lLnc+/KIgQ==", "license": "MIT", "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "@cspotcode/source-map-support": "0.8.1", + "sharp": "0.35.2", + "undici": "7.29.0", + "workerd": "1.20260825.1", + "ws": "8.21.0", + "youch": "4.1.0-beta.10" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.2.tgz", + "integrity": "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.1" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-darwin-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.2.tgz", + "integrity": "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.1" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.1.tgz", + "integrity": "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.1.tgz", + "integrity": "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.1.tgz", + "integrity": "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.1.tgz", + "integrity": "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.1.tgz", + "integrity": "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.1.tgz", + "integrity": "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.1.tgz", + "integrity": "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.1.tgz", + "integrity": "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.1.tgz", + "integrity": "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.1.tgz", + "integrity": "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-linux-arm": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.2.tgz", + "integrity": "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.1" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-linux-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.2.tgz", + "integrity": "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.1" + } + }, + "node_modules/miniflare/node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.2.tgz", + "integrity": "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8.6" + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.1" } }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", + "node_modules/miniflare/node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.2.tgz", + "integrity": "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8.6" + "node": ">=20.9.0" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.1" } }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", + "node_modules/miniflare/node_modules/@img/sharp-linux-s390x": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.2.tgz", + "integrity": "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.6" + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.1" } }, - "node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, + "node_modules/miniflare/node_modules/@img/sharp-linux-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.2.tgz", + "integrity": "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18" + "node": ">=20.9.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.1" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", + "node_modules/miniflare/node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.2.tgz", + "integrity": "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" - } - }, - "node_modules/miniflare": { - "version": "4.20260708.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260708.1.tgz", - "integrity": "sha512-c94O9zRDISdqO18EHt6l0iF/fWgWt8p18PJvRsA/L/NJZ9Cfke3s/F5Blg1XXF7WDutVRzWVWy8Vy4LaT5ifsA==", - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "sharp": "0.34.5", - "undici": "7.28.0", - "workerd": "1.20260708.1", - "ws": "8.21.0", - "youch": "4.1.0-beta.10" + "node": ">=20.9.0" }, - "bin": { - "miniflare": "bootstrap.js" + "funding": { + "url": "https://opencollective.com/libvips" }, - "engines": { - "node": ">=22.0.0" + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1" } }, - "node_modules/miniflare/node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "license": "MIT", + "node_modules/miniflare/node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.2.tgz", + "integrity": "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10.0.0" + "node": ">=20.9.0" }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "funding": { + "url": "https://opencollective.com/libvips" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.1" } }, - "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, + "node_modules/miniflare/node_modules/@img/sharp-win32-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.2.tgz", + "integrity": "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "18 || 20 || >=22" + "node": ">=20.9.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/libvips" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", + "node_modules/miniflare/node_modules/@img/sharp-win32-ia32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.2.tgz", + "integrity": "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/libvips" } }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "license": "BlueOak-1.0.0", + "node_modules/miniflare/node_modules/@img/sharp-win32-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.2.tgz", + "integrity": "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/minisearch": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz", - "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==", - "license": "MIT" - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", + "node_modules/miniflare/node_modules/sharp": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.2.tgz", + "integrity": "sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w==", + "license": "Apache-2.0", "dependencies": { - "minipass": "^7.1.2" + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.4" }, "engines": { - "node": ">= 18" + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.2", + "@img/sharp-darwin-x64": "0.35.2", + "@img/sharp-freebsd-wasm32": "0.35.2", + "@img/sharp-libvips-darwin-arm64": "1.3.1", + "@img/sharp-libvips-darwin-x64": "1.3.1", + "@img/sharp-libvips-linux-arm": "1.3.1", + "@img/sharp-libvips-linux-arm64": "1.3.1", + "@img/sharp-libvips-linux-ppc64": "1.3.1", + "@img/sharp-libvips-linux-riscv64": "1.3.1", + "@img/sharp-libvips-linux-s390x": "1.3.1", + "@img/sharp-libvips-linux-x64": "1.3.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1", + "@img/sharp-libvips-linuxmusl-x64": "1.3.1", + "@img/sharp-linux-arm": "0.35.2", + "@img/sharp-linux-arm64": "0.35.2", + "@img/sharp-linux-ppc64": "0.35.2", + "@img/sharp-linux-riscv64": "0.35.2", + "@img/sharp-linux-s390x": "0.35.2", + "@img/sharp-linux-x64": "0.35.2", + "@img/sharp-linuxmusl-arm64": "0.35.2", + "@img/sharp-linuxmusl-x64": "0.35.2", + "@img/sharp-webcontainers-wasm32": "0.35.2", + "@img/sharp-win32-arm64": "0.35.2", + "@img/sharp-win32-ia32": "0.35.2", + "@img/sharp-win32-x64": "0.35.2" } }, "node_modules/mri": { @@ -17136,9 +13359,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "funding": [ { "type": "github", @@ -17153,21 +13376,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" - }, "node_modules/neotraverse": { "version": "0.6.18", "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", @@ -17197,15 +13405,15 @@ "license": "MIT" }, "node_modules/node-mock-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", - "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.5.tgz", + "integrity": "sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==", "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.51", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", - "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", "license": "MIT", "engines": { "node": ">=18" @@ -17229,18 +13437,6 @@ "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -17253,6 +13449,15 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/oauth4webapi": { + "version": "3.8.8", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.8.tgz", + "integrity": "sha512-8N28E+a/oxfXWBgOMt+ZP/JUf/XR+IFbvkAEPP3gznXOMv9BpAAwiIj0TFNz3tGTPc0ZQ8zmWBNgN1nAys0gng==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -17262,22 +13467,10 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/obug": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", - "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" @@ -17287,28 +13480,6 @@ "node": ">=12.20.0" } }, - "node_modules/octokit": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/octokit/-/octokit-5.0.5.tgz", - "integrity": "sha512-4+/OFSqOjoyULo7eN7EA97DE0Xydj/PW5aIckxqQIoFjFwqXKuFCvXUJObyJfBF9Khu4RL/jlDRI9FPaMGfPnw==", - "license": "MIT", - "dependencies": { - "@octokit/app": "^16.1.2", - "@octokit/core": "^7.0.6", - "@octokit/oauth-app": "^8.0.3", - "@octokit/plugin-paginate-graphql": "^6.0.0", - "@octokit/plugin-paginate-rest": "^14.0.0", - "@octokit/plugin-rest-endpoint-methods": "^17.0.0", - "@octokit/plugin-retry": "^8.0.3", - "@octokit/plugin-throttling": "^11.0.3", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "@octokit/webhooks": "^14.0.0" - }, - "engines": { - "node": ">= 20" - } - }, "node_modules/ofetch": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", @@ -17338,20 +13509,12 @@ "node": ">= 0.8" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", + "peer": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -17379,97 +13542,53 @@ "regex-recursion": "^6.0.2" } }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-limit": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz", - "integrity": "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", "license": "MIT", "dependencies": { - "yocto-queue": "^1.2.1" + "yocto-queue": "^1.1.1" }, "engines": { - "node": ">=20" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-queue": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.3.1.tgz", - "integrity": "sha512-POWdiIPmsUPGwb4FeQ4OBg46aqmcInSWe45CKDsGHiOBiVQM9chqfQTuqhuTzcg2Vz9faTI65at0KkVyVEiCHw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", "license": "MIT", "dependencies": { - "eventemitter3": "^5.0.4", - "p-timeout": "^7.0.0" + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" }, "engines": { - "node": ">=20" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-timeout": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz", - "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", "license": "MIT", "engines": { - "node": ">=20" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-manager-detector": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.7.0.tgz", - "integrity": "sha512-xg1eHpwYL/D/HEdWw2goFZP6vV0FH7W+PZ5rFkGjdIDLtxq7EkzBUeT3m+lndYCt8wKbmofUu1MUdMCXkCk9ZQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.8.0.tgz", + "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", "license": "MIT" }, "node_modules/pagefind": { @@ -17533,28 +13652,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/parse-path": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", - "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", - "license": "MIT", - "dependencies": { - "protocols": "^2.0.0" - } - }, - "node_modules/parse-url": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-9.2.0.tgz", - "integrity": "sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==", - "license": "MIT", - "dependencies": { - "@types/parse-path": "^7.0.0", - "parse-path": "^7.0.0" - }, - "engines": { - "node": ">=14.13.0" - } - }, "node_modules/parse5": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", @@ -17579,33 +13676,12 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/parseley": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", - "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", - "license": "MIT", - "dependencies": { - "leac": "^0.6.0", - "peberminta": "^0.9.0" - }, - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/patch-console": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", "license": "MIT", + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } @@ -17616,39 +13692,11 @@ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "license": "MIT" }, - "node_modules/path-expression-matcher": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.2.tgz", - "integrity": "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/path-to-regexp": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", - "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" }, "node_modules/pathe": { "version": "2.0.3", @@ -17656,110 +13704,6 @@ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "license": "MIT" }, - "node_modules/peberminta": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", - "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==", - "license": "MIT", - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "license": "MIT" - }, - "node_modules/pg": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.22.0.tgz", - "integrity": "sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA==", - "license": "MIT", - "dependencies": { - "pg-connection-string": "^2.14.0", - "pg-pool": "^3.14.0", - "pg-protocol": "^1.15.0", - "pg-types": "2.2.0", - "pgpass": "1.0.5" - }, - "engines": { - "node": ">= 16.0.0" - }, - "optionalDependencies": { - "pg-cloudflare": "^1.4.0" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-cloudflare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz", - "integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==", - "license": "MIT", - "optional": true - }, - "node_modules/pg-connection-string": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz", - "integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==", - "license": "MIT" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "license": "ISC", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-pool": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz", - "integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==", - "license": "MIT", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.15.0.tgz", - "integrity": "sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ==", - "license": "MIT" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "license": "MIT", - "dependencies": { - "split2": "^4.1.0" - } - }, "node_modules/piccolore": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", @@ -17784,58 +13728,10 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/picospinner": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/picospinner/-/picospinner-3.0.0.tgz", - "integrity": "sha512-lGA1TNsmy2bxvRsTI2cV01kfTwKzZjnZSDmF9llYNyMHMrU4sP87lQ5taiIKm88L3cbswjl008nwyGc3WpNvzg==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/pkce-challenge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", - "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/playwright": { - "version": "1.61.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz", - "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==", - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.61.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-core": { - "version": "1.61.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz", - "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==", - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/postcss": { - "version": "8.5.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.17.tgz", - "integrity": "sha512-J7EF+8X+CzRPaJPOv9Ck2wNWJvGnnl3PcNPAdGg6GTLjyVpyQ0yATMSXRFRV01BviT/9Gwuc3rjEyJbDJG9a4w==", + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", "funding": [ { "type": "opencollective", @@ -17852,7 +13748,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -17860,65 +13756,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "license": "ISC", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/postcss-nested": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", @@ -17957,68 +13794,10 @@ "node": ">=4" } }, - "node_modules/postcss-selector-parser": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", - "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" - }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", - "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prettier": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.5.tgz", - "integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -18085,82 +13864,8 @@ "license": "MIT", "funding": { "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/protocols": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", - "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", - "license": "MIT" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.15.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", - "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", - "license": "BSD-3-Clause", - "dependencies": { - "es-define-property": "^1.0.1", - "side-channel": "^1.1.1" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/radix3": { "version": "1.1.2", @@ -18168,23 +13873,6 @@ "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", "license": "MIT" }, - "node_modules/railway": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/railway/-/railway-3.4.1.tgz", - "integrity": "sha512-SKzV9Ugyo1Q1RqQo+cYM3mCsIR69g9qMQBpSC6HKoakdFHgDI6p2EUQ+Sq9vJfuQP+ABkaKL29hixWreZoc/dA==", - "license": "MIT", - "dependencies": { - "@graphql-typed-document-node/core": "^3.2.0", - "graphql": "^16.10.0", - "tsx": "^4.20.0" - }, - "bin": { - "railway-iac-ts": "dist/iac/bin.js" - }, - "engines": { - "node": ">=22" - } - }, "node_modules/range-parser": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", @@ -18198,62 +13886,31 @@ "url": "https://opencollective.com/express" } }, - "node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.7" - } - }, - "node_modules/react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "react": ">=16.13.1" + "react": "^19.2.8" } }, "node_modules/react-hook-form": { - "version": "7.81.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.81.0.tgz", - "integrity": "sha512-ocbmr2p5KBMoAfj4WCUvped33lVi1Kd5DuDUvQDnB6VEAacOjPI/jMbtDdbhco4y9ct4xUuCmMY0b/C9L0QHjw==", + "version": "7.86.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.86.0.tgz", + "integrity": "sha512-4kbWJrh5jPZt1+YqVcXcGKffGcXV/XVbozknLh0Yjh0KhpoAkus21TAQhzRYqNwFkkObmnSvRlZZ3GT+ehoIrA==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -18267,9 +13924,9 @@ } }, "node_modules/react-is": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", - "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz", + "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==", "license": "MIT", "peer": true }, @@ -18278,6 +13935,7 @@ "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.33.0.tgz", "integrity": "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -18312,15 +13970,6 @@ } } }, - "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-remove-scroll": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", @@ -18404,9 +14053,9 @@ } }, "node_modules/recharts": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.9.2.tgz", - "integrity": "sha512-G4fy+Pk46RaXgwWMh+Nzhyo/lbFAVqXo9gtetlyehe6Ehge9CsgDuOTwQDD+i1+llaLktNBiNq4bhnGlDRXFtw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.10.1.tgz", + "integrity": "sha512-QXFrvt6IVcw7eeZCoyXTwkIJAX3Dv1nyVhMicXJ47GsGDDpcN8z6o644DibE9XjpBTThtsomLKnTV6lc+cVFUA==", "license": "MIT", "peer": true, "workspaces": [ @@ -18774,9 +14423,9 @@ } }, "node_modules/remark-smartypants": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", - "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.3.tgz", + "integrity": "sha512-gCaK+ndZ0hYezlqFegHFCVh2CQemsi0Npdh1qVM9bxlUFknjkbP6VmojWhddOCrbK0PbbacmYLWfTULRiT1eWA==", "license": "MIT", "dependencies": { "retext": "^9.0.0", @@ -18803,166 +14452,12 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remotion": { - "version": "4.0.477", - "resolved": "https://registry.npmjs.org/remotion/-/remotion-4.0.477.tgz", - "integrity": "sha512-mxQ8MHmx9YUpxyTSm8hLZW/LGvOzk9b19i02DT9MKKFv+H6ZXkd/1Cn+a908fZWCqM4RRCIy3poXB8KsHiPdow==", - "license": "SEE LICENSE IN LICENSE.md", - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/repomix": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/repomix/-/repomix-1.16.1.tgz", - "integrity": "sha512-xOcuPTo6KstKWxL08wQ5m3PQP0MyHzVU8vsAgsAq4LGAx64nNDhKVZXVdxmFiG2CqiYRqJqhwMoVBkWA32FSow==", - "license": "MIT", - "dependencies": { - "@clack/prompts": "^0.11.0", - "@modelcontextprotocol/sdk": "^1.29.0", - "@repomix/strip-comments": "^2.4.2", - "@repomix/tree-sitter-wasms": "^0.1.17", - "@secretlint/core": "^13.0.2", - "@secretlint/secretlint-rule-preset-recommend": "^13.0.2", - "chokidar": "^5.0.0", - "commander": "^15.0.0", - "fast-xml-builder": "^1.2.1", - "git-url-parse": "^16.1.0", - "globby": "^16.2.0", - "gpt-tokenizer": "^3.4.0", - "handlebars": "^4.7.9", - "iconv-lite": "^0.7.0", - "is-binary-path": "^3.0.0", - "isbinaryfile": "^5.0.2", - "jiti": "^2.7.0", - "jschardet": "^3.1.4", - "json5": "^2.2.3", - "minimatch": "^10.2.5", - "picocolors": "^1.1.1", - "picospinner": "^3.0.0", - "tar": "^7.5.19", - "tinyclip": "^0.1.15", - "tinypool": "^2.1.0", - "valibot": "^1.4.2", - "web-tree-sitter": "^0.26.10", - "zod": "^4.4.3" - }, - "bin": { - "repomix": "bin/repomix.cjs" - }, - "engines": { - "node": ">=22.0.0", - "yarn": ">=1.22.22" - } - }, - "node_modules/repomix/node_modules/@clack/core": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", - "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "sisteransi": "^1.0.5" - } - }, - "node_modules/repomix/node_modules/@clack/prompts": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", - "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", - "license": "MIT", - "dependencies": { - "@clack/core": "0.5.0", - "picocolors": "^1.0.0", - "sisteransi": "^1.0.5" - } - }, - "node_modules/repomix/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "license": "MIT", - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/repomix/node_modules/commander": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", - "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", - "license": "MIT", - "engines": { - "node": ">=22.12.0" - } - }, - "node_modules/repomix/node_modules/readdirp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", - "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", - "license": "MIT", - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/repomix/node_modules/tar": { - "version": "7.5.20", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.20.tgz", - "integrity": "sha512-9FcyK4PA6+WbzlTM9WhQm6vB5W7cP7dUiPsv1g7YDwEQnQ1CGpK3MGlKk/ITVWMk05kHZuBhmVhiv8LZoy/PFQ==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/repomix/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/repomix/node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/request-light": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.7.0.tgz", "integrity": "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==", "license": "MIT" }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -18979,20 +14474,12 @@ "license": "MIT", "peer": true }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/restore-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "license": "MIT", + "peer": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -19065,23 +14552,13 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rolldown": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", - "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.3.tgz", + "integrity": "sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.139.0", + "@oxc-project/types": "=0.143.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -19091,27 +14568,32 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.1.5", - "@rolldown/binding-darwin-arm64": "1.1.5", - "@rolldown/binding-darwin-x64": "1.1.5", - "@rolldown/binding-freebsd-x64": "1.1.5", - "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", - "@rolldown/binding-linux-arm64-gnu": "1.1.5", - "@rolldown/binding-linux-arm64-musl": "1.1.5", - "@rolldown/binding-linux-ppc64-gnu": "1.1.5", - "@rolldown/binding-linux-s390x-gnu": "1.1.5", - "@rolldown/binding-linux-x64-gnu": "1.1.5", - "@rolldown/binding-linux-x64-musl": "1.1.5", - "@rolldown/binding-openharmony-arm64": "1.1.5", - "@rolldown/binding-wasm32-wasi": "1.1.5", - "@rolldown/binding-win32-arm64-msvc": "1.1.5", - "@rolldown/binding-win32-x64-msvc": "1.1.5" - } + "@rolldown/binding-android-arm64": "1.2.3", + "@rolldown/binding-darwin-arm64": "1.2.3", + "@rolldown/binding-darwin-x64": "1.2.3", + "@rolldown/binding-freebsd-x64": "1.2.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.3", + "@rolldown/binding-linux-arm64-gnu": "1.2.3", + "@rolldown/binding-linux-arm64-musl": "1.2.3", + "@rolldown/binding-linux-ppc64-gnu": "1.2.3", + "@rolldown/binding-linux-s390x-gnu": "1.2.3", + "@rolldown/binding-linux-x64-gnu": "1.2.3", + "@rolldown/binding-linux-x64-musl": "1.2.3", + "@rolldown/binding-openharmony-arm64": "1.2.3", + "@rolldown/binding-win32-arm64-msvc": "1.2.3", + "@rolldown/binding-win32-x64-msvc": "1.2.3" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "license": "MIT" }, "node_modules/rollup": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", - "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", "license": "MIT", "dependencies": { "@types/estree": "1.0.9" @@ -19124,73 +14606,35 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.62.2", - "@rollup/rollup-android-arm64": "4.62.2", - "@rollup/rollup-darwin-arm64": "4.62.2", - "@rollup/rollup-darwin-x64": "4.62.2", - "@rollup/rollup-freebsd-arm64": "4.62.2", - "@rollup/rollup-freebsd-x64": "4.62.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", - "@rollup/rollup-linux-arm-musleabihf": "4.62.2", - "@rollup/rollup-linux-arm64-gnu": "4.62.2", - "@rollup/rollup-linux-arm64-musl": "4.62.2", - "@rollup/rollup-linux-loong64-gnu": "4.62.2", - "@rollup/rollup-linux-loong64-musl": "4.62.2", - "@rollup/rollup-linux-ppc64-gnu": "4.62.2", - "@rollup/rollup-linux-ppc64-musl": "4.62.2", - "@rollup/rollup-linux-riscv64-gnu": "4.62.2", - "@rollup/rollup-linux-riscv64-musl": "4.62.2", - "@rollup/rollup-linux-s390x-gnu": "4.62.2", - "@rollup/rollup-linux-x64-gnu": "4.62.2", - "@rollup/rollup-linux-x64-musl": "4.62.2", - "@rollup/rollup-openbsd-x64": "4.62.2", - "@rollup/rollup-openharmony-arm64": "4.62.2", - "@rollup/rollup-win32-arm64-msvc": "4.62.2", - "@rollup/rollup-win32-ia32-msvc": "4.62.2", - "@rollup/rollup-win32-x64-gnu": "4.62.2", - "@rollup/rollup-win32-x64-msvc": "4.62.2", + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", "fsevents": "~2.3.2" } }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -19203,16 +14647,10 @@ "node": ">=6" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, "node_modules/sax": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", - "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz", + "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==", "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" @@ -19224,62 +14662,11 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, - "node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/selderee": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", - "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", - "license": "MIT", - "dependencies": { - "parseley": "^0.12.0" - }, - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, "node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -19313,24 +14700,11 @@ "url": "https://opencollective.com/express" } }, - "node_modules/serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "license": "ISC" }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -19363,56 +14737,23 @@ "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" - } - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" } }, "node_modules/shiki": { @@ -19431,78 +14772,6 @@ "@types/hast": "^3.0.4" } }, - "node_modules/side-channel": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", - "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", - "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -19513,7 +14782,8 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/sisteransi": { "version": "1.0.5", @@ -19546,23 +14816,12 @@ "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", "license": "MIT" }, - "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/slice-ansi": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-9.0.0.tgz", "integrity": "sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA==", "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" @@ -19575,9 +14834,9 @@ } }, "node_modules/smol-toml": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.0.tgz", - "integrity": "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.1.tgz", + "integrity": "sha512-PPlsspAZ4jbMBu5DMFhfUGDQLu/vrL4SyBROVS37x8ynnVmFIs1VPBz1Co8Xks3TvpIaZXmU85y4DrQ+UyVFoQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 18" @@ -19587,16 +14846,12 @@ } }, "node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "deprecated": "The work that was done in this beta branch won't be included in future versions", + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "license": "BSD-3-Clause", - "dependencies": { - "whatwg-url": "^7.0.0" - }, "engines": { - "node": ">= 8" + "node": ">= 12" } }, "node_modules/source-map-js": { @@ -19608,25 +14863,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -19637,20 +14873,12 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "license": "MIT", + "peer": true, "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -19663,6 +14891,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -19673,12 +14902,6 @@ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "license": "MIT" }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", - "license": "MIT" - }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -19745,40 +14968,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/structured-source": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/structured-source/-/structured-source-4.0.0.tgz", - "integrity": "sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==", - "license": "BSD-2-Clause", - "dependencies": { - "boundary": "^2.0.0" - } - }, - "node_modules/style-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", - "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", - "license": "MIT", - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.27.0" - } - }, "node_modules/style-mod": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz", @@ -19803,21 +14992,6 @@ "inline-style-parser": "0.2.7" } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/svgo": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.2.tgz", @@ -19863,6 +15037,7 @@ "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", "license": "MIT", + "peer": true, "engines": { "node": ">=20" }, @@ -19871,9 +15046,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.2.tgz", - "integrity": "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", "license": "MIT" }, "node_modules/tapable": { @@ -19889,36 +15064,12 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/tar": { - "version": "7.5.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", - "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/terminal-size": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/terminal-size/-/terminal-size-4.0.1.tgz", "integrity": "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -19926,90 +15077,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terser": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.0.tgz", - "integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", - "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@minify-html/node": { - "optional": true - }, - "@swc/core": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "@swc/html": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "cssnano": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "html-minifier-terser": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "postcss": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, "node_modules/tiny-inflate": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", @@ -20029,19 +15096,10 @@ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "license": "MIT" }, - "node_modules/tinyclip": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/tinyclip/-/tinyclip-0.1.15.tgz", - "integrity": "sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==", - "license": "MIT", - "engines": { - "node": "^16.14.0 || >= 17.3.0" - } - }, "node_modules/tinyexec": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", - "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", "license": "MIT", "engines": { "node": ">=18" @@ -20063,45 +15121,15 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", - "integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", - "license": "MIT", - "engines": { - "node": "^20.0.0 || >=22.0.0" - } - }, "node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "license": "MIT", "engines": { "node": ">=14.0.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toad-cache": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.4.tgz", - "integrity": "sha512-m1TdR/rvT7kgGJZhspNtXdsdYk0fddFpJJFlG5s+UkPFo6lkLoZ3YLOaovPYjq1R75NP5JfeTlSHaOsE09peCg==", - "license": "MIT", - "engines": { - "node": ">=20" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -20111,15 +15139,6 @@ "node": ">=0.6" } }, - "node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "license": "MIT", - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -20168,9 +15187,10 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.0.tgz", - "integrity": "sha512-eUdUIaCr963q2h5u3+QwvYp0+eqPvn+egeqZUm0hwERCqqx1E3kK5ehbGCvqSE5MQAULr67ww0cA3jKc3YkM1w==", + "version": "4.23.11", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.11.tgz", + "integrity": "sha512-Ry2oTEUnhBdeEdWIztY8kf3/nBGnPnjMLVGL0YfdRXMORuPER5NlKmayqxtxRxwB1xBN+RivRaJfe7PM1rtiyw==", + "devOptional": true, "license": "MIT", "dependencies": { "esbuild": "~0.28.0" @@ -20184,52 +15204,21 @@ "optionalDependencies": { "fsevents": "~2.3.3" } - }, - "node_modules/tsx/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/type-fest": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.8.0.tgz", - "integrity": "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==", - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", - "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", - "license": "MIT", + }, + "node_modules/type-fest": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.9.0.tgz", + "integrity": "sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==", + "license": "(MIT OR CC0-1.0)", + "peer": true, "dependencies": { - "content-type": "^2.0.0", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" + "tagged-tag": "^1.0.0" }, "engines": { - "node": ">= 18" + "node": ">=20" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typesafe-path": { @@ -20266,19 +15255,6 @@ "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", "license": "MIT" }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/ultrahtml": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.7.0.tgz", @@ -20292,9 +15268,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", - "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", + "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", "license": "MIT", "engines": { "node": ">=20.18.1" @@ -20315,18 +15291,6 @@ "pathe": "^2.0.3" } }, - "node_modules/unicorn-magic": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", - "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/unidiff": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unidiff/-/unidiff-1.0.4.tgz", @@ -20511,27 +15475,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/universal-github-app-jwt": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.2.tgz", - "integrity": "sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw==", - "license": "MIT" - }, - "node_modules/universal-user-agent": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", - "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", - "license": "ISC" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/unstorage": { "version": "1.17.5", "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.5.tgz", @@ -20653,9 +15596,9 @@ } }, "node_modules/unstorage/node_modules/readdirp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", - "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", + "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==", "license": "MIT", "engines": { "node": ">= 20.19.0" @@ -20666,9 +15609,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz", + "integrity": "sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==", "funding": [ { "type": "opencollective", @@ -20781,29 +15724,6 @@ "node": ">=0.3.1" } }, - "node_modules/valibot": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.4.2.tgz", - "integrity": "sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg==", - "license": "MIT", - "peerDependencies": { - "typescript": ">=5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -20870,15 +15790,15 @@ } }, "node_modules/vite": { - "version": "8.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", - "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.1.tgz", + "integrity": "sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==", "license": "MIT", "dependencies": { - "lightningcss": "^1.32.0", + "lightningcss": "^1.33.0", "picomatch": "^4.0.5", - "postcss": "^8.5.16", - "rolldown": "~1.1.4", + "postcss": "^8.5.25", + "rolldown": "~1.2.1", "tinyglobby": "^0.2.17" }, "bin": { @@ -20895,7 +15815,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.3.0", + "@vitejs/devtools": "^0.4.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -20907,57 +15827,292 @@ "tsx": "^4.8.1", "yaml": "^2.4.2" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "@vitejs/devtools": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/vite/node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/vite/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", + "node_modules/vite/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", "optional": true, "os": [ - "darwin" + "win32" ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/vitefu": { @@ -21186,18 +16341,6 @@ } } }, - "node_modules/volar-service-typescript/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/volar-service-yaml": { "version": "0.0.71", "resolved": "https://registry.npmjs.org/volar-service-yaml/-/volar-service-yaml-0.0.71.tgz", @@ -21262,15 +16405,6 @@ "npm": ">=7.0.0" } }, - "node_modules/vscode-jsonrpc": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", - "integrity": "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/vscode-languageserver": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", @@ -21357,18 +16491,6 @@ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", "license": "MIT" }, - "node_modules/watchpack": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", - "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/web-namespaces": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", @@ -21379,122 +16501,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/web-tree-sitter": { - "version": "0.26.11", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.26.11.tgz", - "integrity": "sha512-Q5Dm3YTIXSXuH6FxX6RuzX2Qwpc4DPGiYMU87Wg5Z8OIStiQFiUex4zMDc0vBTw78EphaYJacncJghCHzbZptg==", - "license": "MIT" - }, - "node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "license": "BSD-2-Clause" - }, - "node_modules/webpack": { - "version": "5.105.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", - "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.19.0", - "es-module-lexer": "^2.0.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", - "watchpack": "^2.5.1", - "webpack-sources": "^3.3.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-sources": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", - "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "license": "MIT", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/which-pm-runs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", @@ -21525,6 +16531,7 @@ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-6.0.0.tgz", "integrity": "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA==", "license": "MIT", + "peer": true, "dependencies": { "string-width": "^8.1.0" }, @@ -21535,16 +16542,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "license": "MIT" - }, "node_modules/workerd": { - "version": "1.20260708.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260708.1.tgz", - "integrity": "sha512-WAK+Kt/VVCSldH2qSr8lx46XCJ4Q+bdlHNaFqUtOHthBEIB8C1N8HVW+VOLrxDoTCk0NGNv0zajnBeQK4JOB9w==", + "version": "1.20260825.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260825.1.tgz", + "integrity": "sha512-ccS6TEaaRxgONKawiYGnFYUVGfr2pmN1b7mrNtw0ADVhFaYsEIVoCHnQ4UjhM9EJDzuaNgAWFY82nzVrjWpuOA==", "hasInstallScript": true, "license": "Apache-2.0", "bin": { @@ -21554,27 +16555,27 @@ "node": ">=16" }, "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20260708.1", - "@cloudflare/workerd-darwin-arm64": "1.20260708.1", - "@cloudflare/workerd-linux-64": "1.20260708.1", - "@cloudflare/workerd-linux-arm64": "1.20260708.1", - "@cloudflare/workerd-windows-64": "1.20260708.1" + "@cloudflare/workerd-darwin-64": "1.20260825.1", + "@cloudflare/workerd-darwin-arm64": "1.20260825.1", + "@cloudflare/workerd-linux-64": "1.20260825.1", + "@cloudflare/workerd-linux-arm64": "1.20260825.1", + "@cloudflare/workerd-windows-64": "1.20260825.1" } }, "node_modules/wrangler": { - "version": "4.110.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.110.0.tgz", - "integrity": "sha512-xZeXKYi7hxQRF5anL+v77RkufJNpF9f3Eqeyqq2QBsETpLZgh0Agj0jJ6JPtkbgn6ukZdh8OK5egsGPWIditgg==", + "version": "4.126.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.126.0.tgz", + "integrity": "sha512-glDq/nxaeQwue0XMIeupfwlu2jVxnFs+wjDFT71DQuURN5LsVdCwu0Af/1ep10U5xr1rKPGhHDEDkKG9nxE/dg==", "license": "MIT OR Apache-2.0", "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.28.1", - "miniflare": "4.20260708.1", + "miniflare": "5.20260825.0-alpha", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", - "workerd": "1.20260708.1" + "workerd": "1.20260825.1" }, "bin": { "cf-wrangler": "bin/cf-wrangler.js", @@ -21588,7 +16589,7 @@ "fsevents": "2.3.3" }, "peerDependencies": { - "@cloudflare/workers-types": "^5.20260708.1" + "@cloudflare/workers-types": "^5.20260825.1" }, "peerDependenciesMeta": { "@cloudflare/workers-types": { @@ -21596,35 +16597,24 @@ } } }, - "node_modules/wrangler/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/wrangler/node_modules/@cloudflare/kv-asset-handler": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz", + "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==", + "license": "MIT OR Apache-2.0", "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=22.0.0" } }, - "node_modules/wrangler/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "license": "MIT" - }, "node_modules/wrap-ansi": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", - "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.1.tgz", + "integrity": "sha512-M0N4xzyzosiIok3svYlEo1sdLZts/8FPgYH/GPC3wvlmPoRvnoManGMrE54waYj3tISA8w6lsdesfVv67qSr8Q==", "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^6.2.3", - "string-width": "^8.2.0", - "strip-ansi": "^7.1.2" + "string-width": "^8.2.0" }, "engines": { "node": ">=20" @@ -21633,16 +16623,10 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, "node_modules/ws": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", - "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -21660,30 +16644,6 @@ } } }, - "node_modules/xml-naming": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.3.0.tgz", - "integrity": "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/xxhash-wasm": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", @@ -21699,12 +16659,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/yaml": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", @@ -21765,21 +16719,20 @@ } }, "node_modules/yargs": { - "version": "17.7.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", - "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", + "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==", "license": "MIT", "dependencies": { - "cliui": "^8.0.1", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^8.2.1", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { @@ -21791,73 +16744,10 @@ "node": "^20.19.0 || ^22.12.0 || >=23" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yjs": { - "version": "13.6.31", - "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.31.tgz", - "integrity": "sha512-Eq+5BRfbeGyqGVrTJL3bEcr8gKkxPuyuoHmAwpk52fDb8kOVMrfVSTRPd6yiGgX5Fskb96qCRjzjbRjrL4YEnw==", + "version": "13.6.32", + "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.32.tgz", + "integrity": "sha512-lfiJIIC4Xayt5ItynE407ehlE03pCjeOc4hkR4yxxvvNJ4kuiN25B0g+Qp8XagYz361LLL7DCzR5bvFJ81QKtQ==", "license": "MIT", "peer": true, "dependencies": { @@ -21900,9 +16790,9 @@ } }, "node_modules/yoctocolors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", + "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==", "license": "MIT", "engines": { "node": ">=18" @@ -21915,7 +16805,8 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/youch": { "version": "4.1.0-beta.10", diff --git a/package.json b/package.json index 4eb29c23..ff88ab87 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@treeseed/admin", - "version": "0.12.58", + "version": "0.12.59-rc.38", "description": "Treeseed administration portal framework built on @treeseed/core and @treeseed/ui.", "license": "Apache-2.0", "repository": { @@ -20,19 +20,31 @@ "files": [ "README.md", "dist", + "guarantees", + "treeseed.package.yaml", "scripts/verify-driver.ts" ], "publishConfig": { "access": "public" }, + "bin": { + "treeseed-admin-verify-team-ui": "./dist/standards/verifiers/team-ui-contracts.js" + }, "scripts": { + "check:file-lengths": "node --import tsx ./scripts/check-file-lengths.ts && npm run check:file-architecture", + "check:file-architecture": "node --import tsx ./scripts/check-file-architecture.ts", "setup": "npm install", "setup:ci": "npm ci --workspaces=false", - "build": "npm run build:dist", + "brand:sync": "node --import tsx ./scripts/brand/sync-assets.ts", + "build": "npm run build:dist && npm run build:app", "build:dist": "node --import tsx ./scripts/build-dist.ts", + "build:app": "npm run brand:sync && TREESEED_WEB_RUNTIME_TARGET=managed-node astro build --config astro.config.ts", + "build:pages": "npm run brand:sync && TREESEED_WEB_RUNTIME_TARGET=cloudflare astro build --config astro.config.ts", + "dev": "npm run brand:sync && TREESEED_WEB_RUNTIME_TARGET=managed-node node ./node_modules/astro/astro.js dev --config astro.config.ts --port 4322", + "preview": "TREESEED_WEB_RUNTIME_TARGET=managed-node node ./node_modules/astro/astro.js preview --config astro.config.ts --port 4322", "prepare": "node --import tsx ./scripts/prepare.ts", "prepack": "npm run build:dist", - "check": "npm run build:dist && tsc --noEmit", + "check": "npm run check:file-lengths && npm run build:dist && tsc --noEmit && node ./node_modules/astro/astro.js check --root .", "test": "npm run test:unit", "test:unit": "vitest run --config ./vitest.config.ts", "lint": "npm run check", @@ -42,31 +54,34 @@ "verify": "TMPDIR=/tmp node --import tsx ./scripts/verify-driver.ts", "release:setup": "npm run setup:ci", "release:check-tag": "node --import tsx ./scripts/assert-release-tag-version.ts", - "release:verify": "npm run build:dist && npm run test:unit", + "release:verify": "npm run check:file-lengths && npm run build && npm run test:unit", + "release:custody": "node --import tsx ./scripts/release-custody.ts", "release:publish": "node --import tsx ./scripts/publish-package.ts" }, "dependencies": { - "@mdxeditor/editor": "^4.0.2", - "@react-email/render": "^2.0.8", - "@treeseed/core": "0.12.59", - "@treeseed/sdk": "0.12.62", - "@treeseed/ui": "0.12.17", - "libsodium-wrappers-sumo": "^0.7.16", + "@astrojs/starlight": "0.37.6", + "@treeseed/core": ">=0.12.60-rc.1 <0.14.0", + "@treeseed/sdk": "0.13.0-rc.107", + "@treeseed/identity": "0.1.0-rc.13", + "jose": "6.2.12", + "@treeseed/ui": "0.12.18-rc.20", "react": "^19.2.5", "react-dom": "^19.2.6" }, "peerDependencies": { - "astro": "^5.0.0 || ^6.0.0" + "astro": "^5.0.0" }, "devDependencies": { + "@astrojs/cloudflare": "12.6.13", "@types/node": "^24.6.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "astro": "^6.4.5", + "astro": "^5.6.1", "esbuild": "^0.28.0", "tsx": "^4.21.0", "typescript": "^5.9.3", - "vitest": "^4.1.2" + "vitest": "^4.1.2", + "yaml": "^2.9.0" }, "exports": { ".": { @@ -97,10 +112,6 @@ "types": "./dist/commerce.d.ts", "default": "./dist/commerce.js" }, - "./secret-managers": { - "types": "./dist/secret-managers.d.ts", - "default": "./dist/secret-managers.js" - }, "./lib/*": { "types": "./dist/lib/*.d.ts", "default": "./dist/lib/*.js" @@ -109,8 +120,7 @@ "types": "./dist/view-models/*.d.ts", "default": "./dist/view-models/*.js" }, - "./layouts/TreeseedAppLayout.astro": "./dist/layouts/TreeseedAppLayout.astro", - "./layouts/TreeseedOperationalMarketLayout.astro": "./dist/layouts/TreeseedOperationalMarketLayout.astro", - "./layouts/TreeseedPublicLayout.astro": "./dist/layouts/TreeseedPublicLayout.astro" + "./layouts/AppLayout.astro": "./dist/layouts/AppLayout.astro", + "./layouts/PublicLayout.astro": "./dist/layouts/PublicLayout.astro" } } diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 00000000..25e1236f --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,7786 @@ + + + + + + + + + + diff --git a/scripts/assert-release-tag-version.ts b/scripts/assert-release-tag-version.ts index 5103efeb..17565b0a 100644 --- a/scripts/assert-release-tag-version.ts +++ b/scripts/assert-release-tag-version.ts @@ -3,7 +3,7 @@ import { readFileSync } from 'node:fs'; const packageJson = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')); -const semverTagPattern = /^\d+\.\d+\.\d+$/; +const semverTagPattern = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/; const tagName = process.argv[2] || process.env.GITHUB_REF_NAME; if (!tagName) { @@ -12,7 +12,7 @@ if (!tagName) { } if (!semverTagPattern.test(tagName)) { - console.error(`Release tag "${tagName}" must use "{MAJOR}.{MINOR}.{PATCH}", for example "${packageJson.version}".`); + console.error(`Release tag "${tagName}" must use semantic version syntax, for example "${packageJson.version}".`); process.exit(1); } diff --git a/scripts/brand/sync-assets.ts b/scripts/brand/sync-assets.ts new file mode 100644 index 00000000..52089de1 --- /dev/null +++ b/scripts/brand/sync-assets.ts @@ -0,0 +1,13 @@ +#!/usr/bin/env node + +import { copyFileSync, mkdirSync } from 'node:fs'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const canonicalLogo = fileURLToPath(import.meta.resolve('@treeseed/ui/assets/treeseed-logo.svg')); +const publicLogo = resolve('public/logo.svg'); + +mkdirSync(dirname(publicLogo), { recursive: true }); +copyFileSync(canonicalLogo, publicLogo); +// ShellFrame advertises this exact URL on both public and authenticated pages. +copyFileSync(canonicalLogo, resolve('public/favicon.svg')); diff --git a/scripts/build-dist.ts b/scripts/build-dist.ts index 043f1221..c260111d 100644 --- a/scripts/build-dist.ts +++ b/scripts/build-dist.ts @@ -1,19 +1,19 @@ #!/usr/bin/env node -import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'; +import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs'; import { spawnSync } from 'node:child_process'; import { dirname, extname, relative, resolve } from 'node:path'; import { createRequire } from 'node:module'; import { build } from 'esbuild'; +import { parse } from 'yaml'; const packageRoot = resolve(new URL('..', import.meta.url).pathname); const requireFromPackage = createRequire(resolve(packageRoot, 'package.json')); const srcRoot = resolve(packageRoot, 'src'); -const distRoot = resolve(packageRoot, 'dist'); +const liveDistRoot = resolve(packageRoot, 'dist'); +const buildRoot = resolve(packageRoot, '.local', 'build-dist', String(process.pid)); +const distRoot = resolve(buildRoot, 'dist'); const buildLockRoot = resolve(packageRoot, '.treeseed-build-dist.lock'); -const workspaceCoreDistRoot = resolve(packageRoot, '..', 'core', 'dist'); -const workspaceSdkDistRoot = resolve(packageRoot, '..', 'sdk', 'dist'); -const workspaceUiDistRoot = resolve(packageRoot, '..', 'ui', 'dist'); const COMPILE_EXTENSIONS = new Set(['.ts', '.tsx']); const COPY_EXTENSIONS = new Set(['.astro', '.css', '.d.ts', '.js', '.json', '.yaml', '.yml']); @@ -69,29 +69,6 @@ async function acquireBuildLock() { } } -function runtimeDependencyNames() { - const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8')) as { - dependencies?: Record; - }; - return Object.keys(packageJson.dependencies ?? {}); -} - -function ensureWorkspaceRuntimePackageLinks() { - for (const packageName of runtimeDependencyNames()) { - if (!packageName.startsWith('@treeseed/')) { - continue; - } - const runtimePackageRoot = resolve(packageRoot, '..', packageName.slice('@treeseed/'.length)); - if (!existsSync(resolve(runtimePackageRoot, 'package.json'))) { - continue; - } - const linkPath = resolve(packageRoot, 'node_modules', ...packageName.split('/')); - rmSync(linkPath, { recursive: true, force: true }); - mkdirSync(dirname(linkPath), { recursive: true }); - symlinkSync(runtimePackageRoot, linkPath, 'dir'); - } -} - function walkFiles(root) { const files = []; for (const entry of readdirSync(root, { withFileTypes: true })) { @@ -150,40 +127,42 @@ function writeDeclaration(relativePath, source) { writeFileSync(filePath, source, 'utf8'); } -function relativePathForTsconfig(targetPath) { - return relative(packageRoot, targetPath).replaceAll('\\', '/'); +function canonicalize(value) { + if (Array.isArray(value)) return value.map(canonicalize); + if (!value || typeof value !== 'object') return value; + return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalize(value[key])])); } -function existingWorkspaceDeclarationPaths() { - const paths = {}; - if (existsSync(resolve(workspaceCoreDistRoot, 'index.d.ts'))) { - Object.assign(paths, { - '@treeseed/core': [relativePathForTsconfig(resolve(workspaceCoreDistRoot, 'index.d.ts'))], - '@treeseed/core/middleware/editorial-preview': [relativePathForTsconfig(resolve(workspaceCoreDistRoot, 'middleware', 'editorial-preview.d.ts'))], - '@treeseed/core/*/index': [relativePathForTsconfig(resolve(workspaceCoreDistRoot, '*', 'index.d.ts'))], - '@treeseed/core/*': [relativePathForTsconfig(resolve(workspaceCoreDistRoot, '*.d.ts'))], - }); - } - if (existsSync(resolve(workspaceSdkDistRoot, 'index.d.ts'))) { - Object.assign(paths, { - '@treeseed/sdk': [relativePathForTsconfig(resolve(workspaceSdkDistRoot, 'index.d.ts'))], - '@treeseed/sdk/platform/plugin': [relativePathForTsconfig(resolve(workspaceSdkDistRoot, 'platform', 'plugin.d.ts'))], - '@treeseed/sdk/types': [relativePathForTsconfig(resolve(workspaceSdkDistRoot, 'sdk-types.d.ts'))], - '@treeseed/sdk/types/*': [relativePathForTsconfig(resolve(workspaceSdkDistRoot, 'types', '*.d.ts'))], - '@treeseed/sdk/*/index': [relativePathForTsconfig(resolve(workspaceSdkDistRoot, '*', 'index.d.ts'))], - '@treeseed/sdk/*': [relativePathForTsconfig(resolve(workspaceSdkDistRoot, '*.d.ts'))], - }); - } - if (existsSync(resolve(workspaceUiDistRoot, 'index.d.ts'))) { - Object.assign(paths, { - '@treeseed/ui': [relativePathForTsconfig(resolve(workspaceUiDistRoot, 'index.d.ts'))], - '@treeseed/ui/react': [relativePathForTsconfig(resolve(workspaceUiDistRoot, 'react.d.ts'))], - '@treeseed/ui/theme': [relativePathForTsconfig(resolve(workspaceUiDistRoot, 'theme', 'index.d.ts'))], - '@treeseed/ui/*/index': [relativePathForTsconfig(resolve(workspaceUiDistRoot, '*', 'index.d.ts'))], - '@treeseed/ui/*': [relativePathForTsconfig(resolve(workspaceUiDistRoot, '*.d.ts'))], - }); - } - return paths; +function writeGuaranteeCatalog() { + const guaranteesRoot = resolve(packageRoot, 'guarantees'); + const guarantees = walkFiles(guaranteesRoot) + .filter((path) => /\.guarantee\.ya?ml$/u.test(path)) + .map((path) => ({ sourcePath: relative(packageRoot, path).replaceAll('\\', '/'), manifest: parse(readFileSync(path, 'utf8')) })) + .sort((a, b) => String(a.manifest?.id ?? '').localeCompare(String(b.manifest?.id ?? ''))); + const verifierRegistries = walkFiles(resolve(guaranteesRoot, 'verifiers')) + .filter((path) => /\.ya?ml$/u.test(path)) + .map((path) => ({ sourcePath: relative(packageRoot, path).replaceAll('\\', '/'), document: parse(readFileSync(path, 'utf8')) })) + .sort((a, b) => a.sourcePath.localeCompare(b.sourcePath)); + const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8')); + writeDeclaration('standards/guarantee-catalog.json', `${JSON.stringify(canonicalize({ + schemaVersion: 'treeseed.guarantee-catalog/v1', + package: { name: packageJson.name, version: packageJson.version }, + guarantees, + verifierRegistries, + }), null, 2)}\n`); +} + +function writeGuaranteeVerifierContract() { + writeDeclaration('standards/verifiers/team-ui-contract.json', `${JSON.stringify(canonicalize({ + schemaVersion: 'treeseed.guarantee-verifier-artifact/v1', + artifactId: '@treeseed/admin/team-ui-contracts', + entrypoint: 'dist/standards/verifiers/team-ui-contracts.js', + cases: ['admin.team.ui-contracts', 'admin.identity-account.ui-contracts'], + }), null, 2)}\n`); +} + +function relativePathForTsconfig(targetPath) { + return relative(packageRoot, targetPath).replaceAll('\\', '/'); } function ignoreDeprecationsForInstalledTypescript() { @@ -209,13 +188,13 @@ function writeDeclarationTsconfig() { const mergedPaths = { ...(inheritedCompilerOptions.paths ?? {}), ...(baseCompilerOptions.paths ?? {}), - ...existingWorkspaceDeclarationPaths(), }; writeFileSync(tsconfigPath, `${JSON.stringify({ extends: './tsconfig.build.json', compilerOptions: { ...baseCompilerOptions, ignoreDeprecations: baseCompilerOptions.ignoreDeprecations ?? ignoreDeprecationsForInstalledTypescript(), + outDir: relativePathForTsconfig(distRoot), paths: mergedPaths, }, include: baseConfig.include ?? ['src/**/*'], @@ -223,6 +202,24 @@ function writeDeclarationTsconfig() { return tsconfigPath; } +function publishCompletedBuild() { + const stagedFiles = walkFiles(distRoot); + const expected = new Set(stagedFiles.map((filePath) => relative(distRoot, filePath))); + mkdirSync(liveDistRoot, { recursive: true }); + for (const stagedFile of stagedFiles) { + const outputFile = resolve(liveDistRoot, relative(distRoot, stagedFile)); + ensureDir(outputFile); + try { + renameSync(stagedFile, outputFile); + } catch { + cpSync(stagedFile, outputFile); + } + } + for (const liveFile of walkFiles(liveDistRoot)) { + if (!expected.has(relative(liveDistRoot, liveFile))) rmSync(liveFile, { force: true }); + } +} + function emitDeclarations() { const tsconfigPath = writeDeclarationTsconfig(); let localTsc = null; @@ -251,7 +248,7 @@ function emitDeclarations() { async function main() { const releaseBuildLock = await acquireBuildLock(); try { - ensureWorkspaceRuntimePackageLinks(); + rmSync(buildRoot, { recursive: true, force: true }); mkdirSync(distRoot, { recursive: true }); for (const filePath of walkFiles(srcRoot)) { @@ -265,22 +262,27 @@ async function main() { emitDeclarations(); - writeDeclaration('index.d.ts', "export * from './routes.js';\nexport * from './commerce.js';\nexport * from './secret-managers.js';\n"); - writeDeclaration('config.d.ts', "export { createTreeseedTenantSite as createTreeseedAdminSite } from '@treeseed/core/config';\n"); - writeDeclaration('content-config.d.ts', "export { createTreeseedTenantCollections as createTreeseedAdminCollections } from '@treeseed/core/content-config';\n"); - writeDeclaration('plugin.d.ts', "declare const plugin: import('@treeseed/sdk/platform/plugin').TreeseedPlugin;\nexport default plugin;\nexport declare const ADMIN_ENV_SCHEMA: Record;\nexport declare const ADMIN_CAPABILITIES: Record;\n"); - writeDeclaration('routes.d.ts', "import type { TreeseedSiteRouteContribution } from '@treeseed/sdk/platform/plugin';\nexport declare const ADMIN_ROUTES: TreeseedSiteRouteContribution[];\n"); + writeDeclaration('index.d.ts', "export * from './routes.js';\nexport * from './commerce.js';\n"); + writeDeclaration('config.d.ts', "export { createTenantSite as createAdminSite } from '@treeseed/core/config';\n"); + writeDeclaration('content-config.d.ts', "export { createTenantCollections as createAdminCollections } from '@treeseed/core/content-config';\n"); + writeDeclaration('plugin.d.ts', "declare const plugin: import('@treeseed/sdk/site-contracts/plugin').TreeseedPlugin;\nexport default plugin;\nexport declare const ADMIN_ENV_SCHEMA: Record;\nexport declare const ADMIN_CAPABILITIES: Record;\n"); + writeDeclaration('routes.d.ts', "import type { TreeseedSiteRouteContribution } from '@treeseed/sdk/site-contracts/plugin';\nexport declare const ADMIN_ROUTES: TreeseedSiteRouteContribution[];\n"); writeDeclaration('commerce.d.ts', readFileSync(resolve(srcRoot, 'commerce.ts'), 'utf8').replace(/export const DEFAULT_ADMIN_COMMERCE_PROVIDER[\s\S]*$/u, 'export declare const DEFAULT_ADMIN_COMMERCE_PROVIDER: AdminCommerceProvider;\n')); - writeDeclaration('secret-managers.d.ts', readFileSync(resolve(srcRoot, 'secret-managers.ts'), 'utf8').replace(/function unsupportedWrite[\s\S]*$/u, 'export declare const DEFAULT_SECRET_MANAGER_PROVIDERS: TreeseedSecretManagerProvider[];\n')); writeDeclaration('middleware.d.ts', "export declare const onRequest: any;\n"); writeDeclaration('lib/market/catalog.d.ts', "export declare function createMarketTemplateCatalogProvider(...args: any[]): any;\n"); writeDeclaration('lib/market/store.d.ts', "export declare function resolveApiStore(...args: any[]): any;\n"); + writeGuaranteeCatalog(); + writeGuaranteeVerifierContract(); + publishCompletedBuild(); } finally { + rmSync(buildRoot, { recursive: true, force: true }); releaseBuildLock(); } } -main().catch((error) => { +try { + await main(); +} catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exit(1); -}); +} diff --git a/scripts/check-file-architecture.ts b/scripts/check-file-architecture.ts new file mode 100644 index 00000000..fbb627d9 --- /dev/null +++ b/scripts/check-file-architecture.ts @@ -0,0 +1,126 @@ +import { existsSync, readFileSync } from 'node:fs'; +import { dirname } from 'node:path'; +import { spawnSync } from 'node:child_process'; +import ts from 'typescript'; + +function repositoryFiles() { + const result = spawnSync('git', ['ls-files', '-z', '--cached', '--others', '--exclude-standard'], { encoding: 'utf8' }); + if (result.status !== 0) throw new Error(result.stderr || 'Unable to enumerate repository files.'); + return result.stdout.split('\0').filter(Boolean).filter(existsSync); +} + +const violations: string[] = []; +const executableExtensions = /\.(?:astro|c|cjs|cts|ex|exs|h|js|jsx|mjs|mts|py|rs|sh|ts|tsx)$/u; +const excludedSegments = new Set([ + '.astro', '.git', '.treeseed', '_build', 'build', 'coverage', 'deps', 'dist', 'generated', + 'migrations', 'node_modules', 'snapshots', 'target', 'vendor', +]); +const isExcluded = (path: string) => path.split('/').some((segment) => + excludedSegments.has(segment) || segment.startsWith('.treeseed-')); +const isExecutable = (path: string) => executableExtensions.test(path) && !isExcluded(path); +const directFileCounts = new Map(); + +function brandedIdentifier(name: string) { + if (/^TREESEED_[A-Z0-9_]+$/u.test(name)) return false; + if (/^__TREESEED_[A-Z0-9_]+__$/u.test(name)) return false; + return /(?:KnowledgeCoop|TreeSeed|Treeseed|TREESEED_)/u.test(name); +} + +function identifierText(name: ts.DeclarationName | ts.BindingName | undefined): string[] { + if (!name) return []; + if (ts.isIdentifier(name)) return [name.text]; + if (ts.isObjectBindingPattern(name) || ts.isArrayBindingPattern(name)) { + return name.elements.flatMap((element) => + ts.isBindingElement(element) ? identifierText(element.name) : []); + } + return []; +} + +function checkTypeScriptDeclarations(path: string, source: string) { + const executableSource = path.endsWith('.astro') + ? source.match(/^---\s*([\s\S]*?)\s*---/u)?.[1] ?? '' + : source; + const sourceFile = ts.createSourceFile( + path, + executableSource, + ts.ScriptTarget.Latest, + true, + path.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS, + ); + const visit = (node: ts.Node) => { + if ( + ts.isVariableDeclaration(node) + || ts.isParameter(node) + || ts.isFunctionDeclaration(node) + || ts.isClassDeclaration(node) + || ts.isInterfaceDeclaration(node) + || ts.isTypeAliasDeclaration(node) + || ts.isEnumDeclaration(node) + || ts.isMethodDeclaration(node) + || ts.isMethodSignature(node) + || ts.isPropertyDeclaration(node) + || ts.isPropertySignature(node) + || ts.isEnumMember(node) + || ts.isModuleDeclaration(node) + ) { + for (const name of identifierText(node.name)) { + if (brandedIdentifier(name)) violations.push(`${path}: redundant product name in symbol ${name}`); + } + } + ts.forEachChild(node, visit); + }; + visit(sourceFile); +} + +for (const path of repositoryFiles()) { + const basename = path.split('/').at(-1) ?? path; + if (isExecutable(path)) { + directFileCounts.set(dirname(path), (directFileCounts.get(dirname(path)) ?? 0) + 1); + if (/(?:knowledge[-_]?coop|tree[-_]?seed|treeseed)/iu.test(basename)) { + violations.push(`${path}: redundant product name in executable filename`); + } + } + for (const segment of path.split('/').slice(0, -1)) { + if (/^(?:chunk|module|part|section|segment)-\d+$/u.test(segment)) { + violations.push(`${path}: generic numbered directory partition ${segment}`); + } + } + if (/^(?:chunk|module|part|section|segment)-\d+\./u.test(basename)) { + violations.push(`${path}: generic numbered partition`); + } + if (/-\d{1,2}\.(?:scenarios|spec|test)\.[^.]+$/u.test(basename)) { + violations.push(`${path}: ordinal test or scenario suffix`); + } + if (path.startsWith('src/api/routes/') && basename.includes('-through-')) { + violations.push(`${path}: route-order range name`); + } + if (/split-(?:class-methods|large-tests|module-declarations)\.[^.]+$/u.test(basename)) { + violations.push(`${path}: mechanical split script`); + } + if (path.startsWith('scripts/') && /\.(?:spec|test)\.[^.]+$/u.test(basename)) { + violations.push(`${path}: test belongs under tests/`); + } + if (/\.(?:astro|js|jsx|ts|tsx)$/u.test(path)) { + const source = readFileSync(path, 'utf8'); + if (/\b(?:CLI_COMMAND_OVERLAYS|CLI_ONLY_OPERATION_SPECS|MODULE|PART)_\d+\b/u.test(source)) { + violations.push(`${path}: ordinal partition symbol`); + } + checkTypeScriptDeclarations(path, source); + } +} + +for (const [directory, count] of directFileCounts) { + if (count > 10) violations.push(`${directory}: ${count} direct executable files exceeds the limit of 10`); +} + +if (existsSync('test') && existsSync('tests')) { + violations.push('test and tests: duplicate TypeScript test roots'); +} + +if (violations.length > 0) { + console.error('File architecture policy failed:'); + for (const violation of violations) console.error(`- ${violation}`); + process.exit(1); +} + +console.log('File architecture policy passed: filenames and test roots express functional ownership.'); diff --git a/scripts/check-file-lengths.ts b/scripts/check-file-lengths.ts new file mode 100644 index 00000000..acf383ae --- /dev/null +++ b/scripts/check-file-lengths.ts @@ -0,0 +1,47 @@ +import { existsSync, readFileSync } from 'node:fs'; +import { spawnSync } from 'node:child_process'; + +const hardMaximum = 500; +const targetMaximum = 350; +const codeExtensions = /\.(?:astro|cjs|ex|exs|go|js|jsx|mjs|py|rs|svelte|ts|tsx|vue)$/u; +const excludedSegments = new Set([ + '.agent-worktrees', '.git', '.treeseed', '_build', 'build', 'coverage', 'deps', 'dist', + 'generated', 'migrations', 'node_modules', 'snapshots', 'target', 'vendor', +]); + +function isExcluded(path: string) { + const segments = path.split('/'); + return segments.some((segment) => excludedSegments.has(segment)) + || segments.some((segment) => segment.startsWith('.treeseed-')) + || /(?:^|\.)generated\./u.test(segments.at(-1) ?? '') + || /-snapshots(?:\/|$)/u.test(path); +} + +function gitFiles(args: string[]) { + const result = spawnSync('git', ['ls-files', '-z', ...args], { encoding: 'utf8' }); + if (result.status !== 0) throw new Error(result.stderr || 'Unable to enumerate repository files.'); + return result.stdout.split('\0').filter(Boolean); +} + +const codeFiles = [...new Set([ + ...gitFiles([]), + ...gitFiles(['--others', '--exclude-standard']), +])].filter((path) => existsSync(path) && codeExtensions.test(path) && !isExcluded(path)); + +const overLimit: Array<{ path: string; lines: number }> = []; +const aboveTarget: Array<{ path: string; lines: number }> = []; +for (const path of codeFiles) { + const lines = readFileSync(path, 'utf8').split(/\r?\n/u).length; + if (lines > hardMaximum) overLimit.push({ path, lines }); + else if (lines > targetMaximum) aboveTarget.push({ path, lines }); +} + +aboveTarget.sort((left, right) => right.lines - left.lines); +overLimit.sort((left, right) => right.lines - left.lines); +if (aboveTarget.length > 0) console.warn(`File-length target: ${aboveTarget.length} handwritten file(s) are above ${targetMaximum} lines but within the hard limit.`); +if (overLimit.length > 0) { + console.error(`File-length policy failed: ${overLimit.length} handwritten file(s) exceed ${hardMaximum} lines:`); + for (const entry of overLimit) console.error(`- ${entry.lines} ${entry.path}`); + process.exit(1); +} +console.log(`File-length policy passed: no handwritten code exceeds ${hardMaximum} lines.`); diff --git a/scripts/create-component-release.ts b/scripts/create-component-release.ts new file mode 100644 index 00000000..bb802539 --- /dev/null +++ b/scripts/create-component-release.ts @@ -0,0 +1,43 @@ +import { createHash } from 'node:crypto'; +import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { componentReleaseSchema, deploymentDigest, packageRuntimeSchema } from '@treeseed/sdk/deployment'; + +const release = process.env.TREESEED_RELEASE, sourceCommit = process.env.TREESEED_SOURCE_COMMIT; +const adminDigest = process.env.TREESEED_ADMIN_DIGEST; +if (!release || !sourceCommit || !adminDigest) throw new Error('Release, exact source commit, and multi-architecture image digest are required.'); +if (!/^[a-f0-9]{40}$/u.test(sourceCommit) || !/^sha256:[a-f0-9]{64}$/u.test(adminDigest)) throw new Error('Source or image digest is malformed.'); +const track = release.includes('-rc.') ? 'development' : 'stable'; +const revision = Number(process.env.TREESEED_COMPONENT_REVISION ?? '1'); +const debianRelease = `${release.replace(/-rc\.(\d+)$/u, '~rc$1')}-${revision}`; +const compose = readFileSync(resolve('deploy/compose.template.yml'), 'utf8').replace('@ADMIN_IMAGE@', `treeseed/admin@${adminDigest}`); +if (/\bbuild\s*:/u.test(compose) || /@ADMIN_IMAGE@/u.test(compose)) throw new Error('Production Compose bundle is not fully materialized.'); +const composeDigest = `sha256:${createHash('sha256').update(compose).digest('hex')}`; +const runtime = packageRuntimeSchema.parse({ + schemaVersion: 'treeseed.package-runtime/v1' as const, componentId: 'admin', version: debianRelease, + compose: { projectName: 'treeseed-admin', files: [{ path: 'compose.yml', digest: composeDigest }] }, + services: [{ id: 'admin', composeService: 'admin', endpoints: [{ id: 'http', protocol: 'http' as const, port: 4322, + visibility: 'host' as const, defaultAlias: 'admin.treeseed.localhost', aliasOverride: false, tls: 'edge' as const, + authentication: 'application' as const, healthGate: { protocol: 'http' as const, path: '/healthz', timeoutSeconds: 120 } }] }], + stateVolumes: [], migrations: [], requiredCapabilities: ['docker-compose'], + configuration: { + environment: ['TREESEED_SITE_URL', 'TREESEED_IDENTITY_ISSUER', 'TREESEED_IDENTITY_ACCOUNT_URL', + 'TREESEED_IDENTITY_WORKLOAD_CLIENT_ID'].map(name => ({ name, required: true, source: 'configuration' as const })), + secretEnvironment: [{ name: 'TREESEED_IDENTITY_WORKLOAD_PRIVATE_KEY', required: true }], + secretFiles: [], files: [], + }, + dependencies: [{ id: 'api', capability: 'control-plane-api', locality: 'either' as const, optional: false }], +}); +const tagUrl = `https://hub.docker.com/r/treeseed/admin/tags?name=${encodeURIComponent(release)}`; +const bundle = componentReleaseSchema.parse({ + schemaVersion: 'treeseed.component-release/v1', componentId: 'admin', release: debianRelease, applicationVersion: release, + revision, track, source: { repository: 'treeseed-ai/admin', commit: sourceCommit }, + stableBase: track === 'development' ? { releaseRange: '>=0.12.0 <0.14.0', compatibilityId: 'treeseed-linux-amd64-v1', catalogDigest: null } : null, + packages: [{ name: 'treeseed-component-admin', version: debianRelease, architecture: 'all', origin: 'TreeSeed Deployment', order: 25 }], + images: [{ role: 'admin', repository: 'treeseed/admin', digest: adminDigest, platforms: ['linux/amd64', 'linux/arm64'], consumers: ['admin'] }], + runtime, runtimeDigest: deploymentDigest(runtime), rollback: { compatible: true, requiresBackup: false }, + evidence: { provenance: [tagUrl], sboms: [tagUrl], vulnerabilities: [] }, +}); +const output = resolve('release-assets'); mkdirSync(output, { recursive: true }); +writeFileSync(resolve(output, 'compose.yml'), compose); +writeFileSync(resolve(output, 'component-release.json'), `${JSON.stringify(bundle, null, 2)}\n`); diff --git a/scripts/development/live-web.ts b/scripts/development/live-web.ts new file mode 100644 index 00000000..32ecdf45 --- /dev/null +++ b/scripts/development/live-web.ts @@ -0,0 +1,39 @@ +import { spawn,type ChildProcess } from 'node:child_process'; +import { resolve } from 'node:path'; +import { unwatchFile,watchFile } from 'node:fs'; + +const workspace=process.env.TREESEED_DEVELOPMENT_WORKSPACE_ROOT?.trim(); +const session=process.env.TREESEED_DEVELOPMENT_SESSION_ID?.trim(); +const markers=workspace&&session?['sdk','ui','core'].map((project)=>resolve(workspace,'packages',project,'.treeseed','cache','development-sessions',session,'package','current','dist','.treeseed-build-complete.json')):[]; +const astro=resolve('node_modules/astro/astro.js'); +let child:ChildProcess|undefined; +let timer:NodeJS.Timeout|undefined; +let stopping=false; + +function start() { + if(stopping)return; + child=spawn(process.execPath,[astro,'dev','--config','astro.config.ts','--port','4322','--host','0.0.0.0'],{cwd:process.cwd(),env:process.env,stdio:'inherit'}); + child.once('exit',(code,signal)=>{child=undefined;if(!stopping&&code&&!signal)process.stderr.write(`Admin development server exited with code ${code}; waiting for a dependency rebuild.\n`);}); +} + +function restart() { + if(timer)clearTimeout(timer); + timer=setTimeout(()=>{ + const previous=child; + if(!previous)return start(); + previous.once('exit',start); + previous.kill('SIGTERM'); + },500); +} + +function stop(signal:NodeJS.Signals) { + stopping=true; + if(timer)clearTimeout(timer); + for(const marker of markers)unwatchFile(marker); + if(child)child.kill(signal); +} + +for(const marker of markers)watchFile(marker,{interval:250},(current,prior)=>{if(current.mtimeMs&¤t.mtimeMs!==prior.mtimeMs)restart();}); +process.once('SIGINT',()=>stop('SIGINT')); +process.once('SIGTERM',()=>stop('SIGTERM')); +start(); diff --git a/scripts/development/source-updates.ts b/scripts/development/source-updates.ts new file mode 100644 index 00000000..a84f7d9f --- /dev/null +++ b/scripts/development/source-updates.ts @@ -0,0 +1,19 @@ +const publicId = 'virtual:treeseed-source-update'; +const resolvedId = '\0' + publicId; + +/** Timestamp of the source generation served by Vite, not of the HTTP request. */ +export function sourceUpdates(enabled: boolean, clock = () => Date.now()) { + let updatedAt = enabled ? new Date(clock()).toISOString() : null; + return { + name: 'treeseed-source-updates', + resolveId(id: string) { if (id === publicId) return resolvedId; }, + load(id: string) { if (id === resolvedId) return `export default ${JSON.stringify(updatedAt)};`; }, + handleHotUpdate(context: any) { + if (!enabled) return; + updatedAt = new Date(clock()).toISOString(); + const module = context.server.moduleGraph.getModuleById(resolvedId); + if (module) context.server.moduleGraph.invalidateModule(module); + context.server.ws.send({type: 'custom', event: 'treeseed:source-update', data: {updatedAt}}); + }, + }; +} diff --git a/scripts/publish-package.ts b/scripts/publish-package.ts index d49084f9..ba58095f 100644 --- a/scripts/publish-package.ts +++ b/scripts/publish-package.ts @@ -1,17 +1,26 @@ #!/usr/bin/env node import { spawnSync } from 'node:child_process'; +import { resolve } from 'node:path'; const packageName = '@treeseed/admin'; const extraArgs = process.argv.slice(2); const tagName = process.env.GITHUB_REF_NAME; +const semverTagPattern = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/; -if (tagName && !/^\d+\.\d+\.\d+$/.test(tagName)) { - console.error(`Refusing to publish ${packageName} from non-stable tag "${tagName}".`); +if (tagName && !semverTagPattern.test(tagName)) { + console.error(`Refusing to publish ${packageName} from invalid semantic version tag "${tagName}".`); process.exit(1); } -const npmArgs = ['publish', '.', '--access', 'public']; +if (extraArgs.some((argument) => argument === '--tag' || argument.startsWith('--tag='))) { + console.error('release:publish owns npm dist-tag selection; a caller cannot override --tag.'); + process.exit(1); +} + +const npmDistTag = tagName?.includes('-') ? 'next' : 'latest'; +const publishTarget = extraArgs.length > 0 ? resolve(process.cwd(), extraArgs.shift()!) : '.'; +const npmArgs = ['publish', publishTarget, '--access', 'public', '--tag', npmDistTag]; if (process.env.GITHUB_ACTIONS === 'true') { npmArgs.push('--provenance'); diff --git a/scripts/release-custody.ts b/scripts/release-custody.ts new file mode 100644 index 00000000..14699b39 --- /dev/null +++ b/scripts/release-custody.ts @@ -0,0 +1,32 @@ +import { execFileSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'; +import { basename, resolve } from 'node:path'; +import { releaseEvidenceSchema } from '@treeseed/sdk/development'; + +const root = resolve(import.meta.dirname, '..'); +const sha256 = (path: string) => `sha256:${createHash('sha256').update(readFileSync(path)).digest('hex')}` as const; +const evidencePath = resolve(root, process.argv[3] ?? 'release-assets/release-evidence-v1.json'); +if (process.argv[2] === 'seal') { + const output = resolve(root, process.argv[4] ?? 'release-assets'); + const pkg = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')) as { name: string; version: string }; + const sourceCommit = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim(); + const imageDigest = process.env.TREESEED_ADMIN_DIGEST; + if (!/^sha256:[a-f0-9]{64}$/u.test(imageDigest ?? '')) throw new Error('Exact Admin OCI manifest digest is required.'); + const artifacts: Array<{ id: string; kind: 'oci-image' | 'npm-package' | 'archive' | 'sbom' | 'component-manifest' | 'compose'; identity: string; digest: `sha256:${string}`; mediaType: string; size?: number }> = [{ id: 'admin-image', kind: 'oci-image', identity: `treeseed/admin@${imageDigest}`, digest: imageDigest as `sha256:${string}`, mediaType: 'application/vnd.oci.image.index.v1+json' }]; + for (const name of readdirSync(output).filter((name) => name !== basename(evidencePath)).sort()) { + const path = resolve(output, name); if (!statSync(path).isFile()) continue; + const kind = name.endsWith('.tgz') ? 'npm-package' as const : name === 'component-release.json' ? 'component-manifest' as const : name === 'compose.yml' ? 'compose' as const : name.includes('sbom') ? 'sbom' as const : 'archive' as const; + const id = name === 'admin-pages.tar.gz' ? 'admin-pages' : `asset-${createHash('sha256').update(name).digest('hex').slice(0, 12)}`; + artifacts.push({ id, kind, identity: name, digest: sha256(path), mediaType: name.endsWith('.json') ? 'application/json' : name.endsWith('.yml') ? 'application/yaml' : 'application/gzip', size: statSync(path).size }); + } + const receiptDigest = `sha256:${createHash('sha256').update(`${sourceCommit}\n${artifacts.map(({ digest }) => digest).join('\n')}`).digest('hex')}` as const; + const evidence = releaseEvidenceSchema.parse({ schemaVersion: 'treeseed.release-evidence/v1', candidate: { id: `candidate-${sourceCommit.slice(0, 12)}`, receiptDigest, sourceCommit, stagingRef: process.env.GITHUB_REF ?? 'refs/heads/staging', workflowRunId: process.env.GITHUB_RUN_ID ?? '1', createdAt: new Date().toISOString() }, packages: [{ projectId: 'admin', name: pkg.name, version: pkg.version, minimumBump: 'patch' }], artifacts, contractBundles: [], compatibilityAttestations: [], verification: { status: 'passed', operations: ['npm run verify:direct', 'multi-architecture OCI build'], completedAt: new Date().toISOString() } }); + writeFileSync(evidencePath, `${JSON.stringify(evidence, null, 2)}\n`); +} else if (process.argv[2] === 'verify') { + const evidence = releaseEvidenceSchema.parse(JSON.parse(readFileSync(evidencePath, 'utf8'))); + const commit = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim(); + if (evidence.candidate.sourceCommit !== commit) throw new Error('Candidate source commit differs from tagged commit.'); + if (process.env.GITHUB_REF?.startsWith('refs/tags/') && process.env.GITHUB_REF_NAME !== evidence.packages[0]?.version) throw new Error('Tag does not match sealed package version.'); + for (const artifact of evidence.artifacts.filter(({ kind }) => kind !== 'oci-image')) if (sha256(resolve(evidencePath, '..', artifact.identity)) !== artifact.digest) throw new Error(`Candidate artifact digest mismatch: ${artifact.identity}.`); +} else throw new Error('release:custody requires seal or verify.'); diff --git a/scripts/release/reissue-component.ts b/scripts/release/reissue-component.ts new file mode 100644 index 00000000..485cd5ac --- /dev/null +++ b/scripts/release/reissue-component.ts @@ -0,0 +1,33 @@ +import { createHash } from 'node:crypto'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { componentReleaseSchema, deploymentDigest } from '@treeseed/sdk/deployment'; + +/** A packaging-only revision, never an application/image rebuild or an edit to + * an existing asset. The caller pins the original published artifact bytes. */ +export function reissueAdminComponent(bytes: Buffer, sha256: string, revision: number) { + if (bytes.length > 4_194_304 || !/^[a-f0-9]{64}$/u.test(sha256) + || createHash('sha256').update(bytes).digest('hex') !== sha256) throw new Error('Published component checksum mismatch'); + const original = componentReleaseSchema.parse(JSON.parse(bytes.toString('utf8'))); + if (original.componentId !== 'admin' || original.source.repository !== 'treeseed-ai/admin' + || original.track !== 'development' || !/^\d+\.\d+\.\d+-rc\.\d+$/u.test(original.applicationVersion) + || !Number.isSafeInteger(revision) || revision !== original.revision + 1 + || original.packages.length !== 1 || original.packages[0]!.name !== 'treeseed-component-admin' + || original.release !== `${original.applicationVersion.replace('-rc.', '~rc')}-${original.revision}` + || original.runtime.version !== original.release || original.packages[0]!.version !== original.release) + throw new Error('Exact development Admin packaging revision required'); + if (deploymentDigest(original.runtime) === original.runtimeDigest) throw new Error('Component runtime integrity already valid'); + const release = `${original.applicationVersion.replace('-rc.', '~rc')}-${revision}`; + const runtime = { ...original.runtime, version: release }; + return componentReleaseSchema.parse({ ...original, release, revision, runtime, + runtimeDigest: deploymentDigest(runtime), packages: original.packages.map(item => ({ ...item, version: release })) }); +} + +if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { + const [input, digest, revision, output] = process.argv.slice(2); + if (!input || !digest || !revision || !output) throw new Error('Input artifact, SHA256, next revision and output required'); + const component = reissueAdminComponent(readFileSync(input), digest, Number(revision)); + writeFileSync(output, `${JSON.stringify(component, null, 2)}\n`, { flag: 'wx' }); + console.log(JSON.stringify({ componentId: component.componentId, release: component.release, runtimeDigest: component.runtimeDigest })); +} diff --git a/scripts/repair-api-client-extraction.ts b/scripts/repair-api-client-extraction.ts new file mode 100644 index 00000000..917553e8 --- /dev/null +++ b/scripts/repair-api-client-extraction.ts @@ -0,0 +1,36 @@ +import { readFileSync, readdirSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; + +const directory = resolve('src/lib/market/api-client'); +const methodFiles = readdirSync(directory) + .filter((file) => file.endsWith('.ts') && !['interface.ts', 'methods.ts'].includes(file)) + .sort(); +const methods: Array<{ file: string; name: string }> = []; + +for (const file of methodFiles) { + const path = resolve(directory, file); + let source = readFileSync(path, 'utf8'); + source = source.replace(/import \{ ([^}]+) \} from "\.\.\/api-client\.ts";/u, (_statement, names: string) => { + const imported = names.split(',').map((name) => name.trim()); + const types = imported.filter((name) => ['AstroLike', 'ApiClientFacade'].includes(name)); + const values = imported.filter((name) => !types.includes(name)); + return [ + types.length > 0 ? `import type { ${types.join(', ')} } from '../api-client.ts';` : '', + values.length > 0 ? `import { ${values.join(', ')} } from '../api-client.ts';` : '', + ].filter(Boolean).join('\n'); + }); + writeFileSync(path, source); + const match = /export (?:async )?function (\w+Method)\b/u.exec(source); + if (match) methods.push({ file, name: match[1]! }); +} + +const properties = methods.map(({ file, name }) => + `\t\t${name.replace(/Method$/u, '')}: typeof import('./${file}').${name};`).join('\n'); +writeFileSync(resolve(directory, 'interface.ts'), `declare module '../api-client.ts' { +\tinterface ApiClientFacade { +${properties} +\t} +} + +export {}; +`); diff --git a/scripts/verify-driver.ts b/scripts/verify-driver.ts index e5fd3583..c579bfc7 100644 --- a/scripts/verify-driver.ts +++ b/scripts/verify-driver.ts @@ -2,33 +2,19 @@ import { spawnSync } from 'node:child_process'; -function runDirectVerify() { - const result = spawnSync('npm', ['run', 'verify:direct'], { - cwd: process.cwd(), - env: process.env, - stdio: 'inherit', - }); - process.exit(result.status ?? 1); +if (process.env.TREESEED_VERIFY_ENTRYPOINT_CHECK === 'true') { + process.exit(0); } -const entrypointCheckOnly = process.env.TREESEED_VERIFY_ENTRYPOINT_CHECK === 'true'; +const driver = process.env.TREESEED_VERIFY_DRIVER ?? 'direct'; +const command = driver === 'act' + ? { executable: 'npx', arguments: ['act', '--job', 'verify'] } + : { executable: 'npm', arguments: ['run', 'verify:direct'] }; -try { - await import('@treeseed/sdk/scripts/verify-driver'); - if (entrypointCheckOnly) { - process.exit(0); - } -} catch (error) { - if (error && typeof error === 'object' && 'code' in error && error.code === 'ERR_MODULE_NOT_FOUND') { - if (entrypointCheckOnly) { - process.stderr.write('Treeseed admin verify: @treeseed/sdk is required for verify entrypoint resolution.\n'); - process.exit(1); - } - if (process.env.TREESEED_VERIFY_DRIVER === 'act') { - process.stderr.write('Treeseed admin verify: `act` mode requires @treeseed/sdk to be installed.\n'); - process.exit(1); - } - runDirectVerify(); - } - throw error; -} +const result = spawnSync(command.executable, command.arguments, { + cwd: process.cwd(), + stdio: 'inherit', + env: process.env, +}); + +process.exit(result.status ?? 1); diff --git a/src/capabilities/questions.ts b/src/capabilities/questions.ts deleted file mode 100644 index 9d9fe5f3..00000000 --- a/src/capabilities/questions.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { - CapabilityDefinition, - CollectionFilterField, - NavigationItem, - ResourceUiSchema, -} from '@treeseed/ui'; - -export const QUESTION_ACTION_IDS = { - read: 'question.read', - create: 'question.create', - edit: 'question.edit', - save: 'question.save', - export: 'question.export', -} as const; - -export const QUESTION_STATUS_OPTIONS = [ - { label: 'Any status', value: '' }, - { label: 'Recorded', value: 'recorded' }, - { label: 'Planned', value: 'planned' }, - { label: 'Live', value: 'live' }, - { label: 'In progress', value: 'in progress' }, - { label: 'Exploratory', value: 'exploratory' }, - { label: 'Speculative', value: 'speculative' }, -] as const; - -export const QUESTION_TYPE_OPTIONS = [ - { label: 'Any type', value: '' }, - { label: 'Strategy', value: 'strategy' }, - { label: 'Implementation', value: 'implementation' }, - { label: 'Research', value: 'research' }, - { label: 'Evaluation', value: 'evaluation' }, -] as const; - -export const QUESTION_WORK_NAV_ENTRY: NavigationItem = { - label: 'Questions', - href: '/app/work/questions', -}; - -export const QUESTION_CAPABILITY: CapabilityDefinition = { - id: 'work.questions', - label: 'Questions', - scope: 'project', - path: '/app/work/questions', - template: 'collection', - resourceType: 'question', - access: ['signed-in principal', 'active team', 'project work policy'], - actions: Object.values(QUESTION_ACTION_IDS), - primaryAction: QUESTION_ACTION_IDS.create, - secondaryActions: [QUESTION_ACTION_IDS.export], - help: { - topicIds: ['work-content', 'questions'], - summary: 'Questions capture the uncertainty that directs project work, proposals, decisions, and knowledge generation.', - feedbackType: 'question', - }, - feedbackContext: ['route', 'team', 'project', 'capability', 'resource'], -}; - -export const QUESTION_RESOURCE_SCHEMA: ResourceUiSchema = { - type: 'question', - display: { - label: 'Question', - pluralLabel: 'Questions', - summaryField: 'summary', - statusField: 'status', - }, - collection: { - emptyTitle: 'No question content yet', - emptyDescription: 'Question records appear from src/content/questions.', - displayModes: ['cards', 'table'], - }, - actions: { - primary: [QUESTION_ACTION_IDS.create, QUESTION_ACTION_IDS.edit, QUESTION_ACTION_IDS.save], - secondary: [QUESTION_ACTION_IDS.export], - }, - help: QUESTION_CAPABILITY.help, -}; - -export function questionCollectionFilters(values: { q?: string; status?: string; questionType?: string }): CollectionFilterField[] { - return [ - { key: 'q', label: 'Search', type: 'search', value: values.q ?? '' }, - { key: 'status', label: 'Status', type: 'select', value: values.status ?? '', options: [...QUESTION_STATUS_OPTIONS] }, - { key: 'questionType', label: 'Type', type: 'select', value: values.questionType ?? '', options: [...QUESTION_TYPE_OPTIONS] }, - ]; -} diff --git a/src/commerce.ts b/src/commerce.ts index 909cba20..f5448714 100644 --- a/src/commerce.ts +++ b/src/commerce.ts @@ -1,4 +1,4 @@ -import type { CatalogItemOfferMode } from '@treeseed/sdk/types'; +import type { CatalogItemOfferMode } from '@treeseed/sdk/site-contracts/catalog'; export interface AdminOffer { id: string; diff --git a/src/components/LiveDevelopmentIndicator.astro b/src/components/LiveDevelopmentIndicator.astro new file mode 100644 index 00000000..2d19fde8 --- /dev/null +++ b/src/components/LiveDevelopmentIndicator.astro @@ -0,0 +1,22 @@ +--- +import Badge from '@treeseed/ui/components/astro/data/Badge.astro'; +import Timestamp from '@treeseed/ui/components/astro/data/Timestamp.astro'; +import updatedAt from 'virtual:treeseed-source-update'; +interface Props { timeZone?: string } +const {timeZone = 'UTC'} = Astro.props; +--- +{import.meta.env.DEV && updatedAt && + Live development Local source - last updated: +} + diff --git a/src/components/account/AccountNavigation.astro b/src/components/account/AccountNavigation.astro new file mode 100644 index 00000000..91ae29d0 --- /dev/null +++ b/src/components/account/AccountNavigation.astro @@ -0,0 +1,18 @@ +--- +import SurfaceTabs from '@treeseed/ui/components/astro/shell/SurfaceTabs.astro'; +import { ACCOUNT_SECTIONS } from '../../lib/accounts/navigation'; + +interface Props { + profileHref: string; +} + +const { profileHref } = Astro.props as Props; +const items = [ + ...ACCOUNT_SECTIONS, + { id: 'public-profile', label: 'Public profile', href: profileHref }, +]; +--- + + + + diff --git a/src/components/command/SituationDeck.astro b/src/components/command/SituationDeck.astro new file mode 100644 index 00000000..60c07694 --- /dev/null +++ b/src/components/command/SituationDeck.astro @@ -0,0 +1,21 @@ +--- +import ActionList from '@treeseed/ui/components/astro/data/ActionList.astro'; +import Timestamp from '@treeseed/ui/components/astro/data/Timestamp.astro'; +import EmptyState from '@treeseed/ui/components/astro/surface/EmptyState.astro'; +import Panel from '@treeseed/ui/components/astro/surface/Panel.astro'; +import type { CommandSituation } from '../../view-models/command/situations.ts'; + +interface Props { situations: CommandSituation[] } +const { situations } = Astro.props as Props; +--- + + + {situations.length ? ( + + ({ title: item.title, description: item.description, href: item.href, meta: item.status, tone: item.tone, actionLabel: item.actionLabel }))} /> + + {situations.map((item) => {item.title}: {item.evidence}{item.inferred ? ', inferred condition' : ''}{item.timestamp ? <> at > : null})} + + + ) : } + diff --git a/src/components/runtime/PublicNotFound.astro b/src/components/runtime/PublicNotFound.astro new file mode 100644 index 00000000..e54d751b --- /dev/null +++ b/src/components/runtime/PublicNotFound.astro @@ -0,0 +1,18 @@ +--- +import Button from '@treeseed/ui/components/astro/forms/Button.astro'; +import PageHeader from '@treeseed/ui/components/astro/layout/PageHeader.astro'; +import Panel from '@treeseed/ui/components/astro/surface/Panel.astro'; +import TreeseedPublicLayout from '../../layouts/PublicLayout.astro'; + +interface Props { currentPath: string; description?: string } +const { currentPath, description = 'This TreeSeed page does not exist or is not publicly available.' } = Astro.props as Props; +--- + + + + + + Go homeSign in + + + diff --git a/src/components/team/TeamAccessDetails.astro b/src/components/team/TeamAccessDetails.astro new file mode 100644 index 00000000..a665e0e6 --- /dev/null +++ b/src/components/team/TeamAccessDetails.astro @@ -0,0 +1,22 @@ +--- +import DisclosureList from '@treeseed/ui/components/astro/data/DisclosureList.astro'; +import { capabilityDisplay, roleDisplay } from '../../lib/teams/access-display'; + +interface Props { + role: string; + capabilities?: string[]; + open?: boolean; +} + +const { role, capabilities = [], open = false } = Astro.props as Props; +const display = roleDisplay(role); +const items = capabilities.map((capability) => capabilityDisplay(capability)); +--- + + diff --git a/src/components/team/TeamNavigation.astro b/src/components/team/TeamNavigation.astro new file mode 100644 index 00000000..75a63650 --- /dev/null +++ b/src/components/team/TeamNavigation.astro @@ -0,0 +1,28 @@ +--- +import SurfaceTabs from '@treeseed/ui/components/astro/shell/SurfaceTabs.astro'; + +interface Props { + team: { id: string; name: string; status?: string; metadata?: { visibility?: string } }; + currentPath: string; + canManage?: boolean; + isOwner?: boolean; +} + +const { team, currentPath, canManage = false, isOwner = false } = Astro.props as Props; +const root = `/app/teams/${encodeURIComponent(team.id)}`; +const items = [ + { id: 'all-teams', label: 'All teams', href: '/app/teams', visible: true }, + { id: 'overview', label: 'Overview', href: root, visible: true }, + { id: 'members', label: 'Members', href: `${root}/members`, visible: true }, + { id: 'settings', label: 'Settings', href: `${root}/edit`, visible: canManage }, + { id: 'lifecycle', label: 'Lifecycle', href: `${root}/delete`, visible: isOwner }, + { id: 'public-profile', label: 'Public profile', href: `/t/${encodeURIComponent(team.name)}`, visible: team.status !== 'archived' && team.metadata?.visibility === 'public' }, +]; +const normalizedPath = currentPath.replace(/\/+$/u, ''); +const visibleItems = items.filter((item) => item.visible); +const current = visibleItems.find((item) => normalizedPath === item.href)?.id ?? 'overview'; +--- + + + + diff --git a/src/components/work/DirectionContentForm.astro b/src/components/work/DirectionContentForm.astro deleted file mode 100644 index c085d660..00000000 --- a/src/components/work/DirectionContentForm.astro +++ /dev/null @@ -1,125 +0,0 @@ ---- -import Button from '@treeseed/ui/components/astro/forms/Button.astro'; -import Field from '@treeseed/ui/components/astro/forms/Field.astro'; -import FormActions from '@treeseed/ui/components/astro/forms/FormActions.astro'; -import Select from '@treeseed/ui/components/astro/forms/Select.astro'; -import TextInput from '@treeseed/ui/components/astro/forms/TextInput.astro'; -import Textarea from '@treeseed/ui/components/astro/forms/Textarea.astro'; -import MarkdownField from '@treeseed/ui/components/astro/app/controls/MarkdownField.astro'; -import type { DirectionCollection } from '../../view-models/operating-loop.vm.js'; - -interface ProjectOption { - label: string; - value: string; -} - -interface Props { - collection: DirectionCollection; - mode: 'create' | 'edit'; - projectOptions: ProjectOption[]; - selectedProjectId: string; - initialData?: Record; - body?: string; - slug?: string; - fallbackHref: string; -} - -const { - collection, - mode, - projectOptions, - selectedProjectId, - initialData = {}, - body = '', - slug = '', - fallbackHref, -} = Astro.props as Props; - -const labels: Record }> = { - objectives: { singular: 'objective', typeLabel: 'Horizon', typeName: 'timeHorizon', options: [{ label: 'Near-term', value: 'near-term' }, { label: 'Mid-term', value: 'mid-term' }, { label: 'Long-term', value: 'long-term' }] }, - notes: { singular: 'note', typeLabel: 'Type' }, - proposals: { singular: 'proposal', typeLabel: 'Proposal type', typeName: 'proposalType', options: [{ label: 'Implementation', value: 'implementation' }, { label: 'Strategy', value: 'strategy' }, { label: 'Policy', value: 'policy' }, { label: 'Research', value: 'research' }] }, - decisions: { singular: 'decision', typeLabel: 'Decision type', typeName: 'decisionType', options: [{ label: 'Approved', value: 'approved' }, { label: 'Rejected', value: 'rejected' }, { label: 'Deferred', value: 'deferred' }, { label: 'Request changes', value: 'request_changes' }, { label: 'Superseded', value: 'superseded' }] }, -}; -const label = labels[collection]; -const dataId = `${collection}-${mode}-data`; -const formId = `${collection}-${mode}-form`; -const statusId = `${collection}-${mode}-status`; -const serialized = JSON.stringify({ collection, projectId: selectedProjectId }).replace(/ - {mode === 'edit' ? ( - <> - - - - > - ) : null} - - - - - - - - {mode === 'create' ? ( - - - - ) : null} - - - - {label.typeName && label.options ? ( - - - - ) : null} - {collection === 'decisions' ? ( - - - - ) : null} - {collection === 'notes' ? ( - - - - ) : collection !== 'decisions' ? ( - - - - ) : null} - - - - {collection === 'decisions' ? ( - - ) : collection !== 'notes' ? ( - - ) : null} - {collection === 'proposals' ? ( - - - - - - ) : null} - {collection === 'decisions' ? ( - - ) : null} - - - {mode === 'create' ? `Create ${label.singular}` : `Save ${label.singular}`} - Cancel - - - - - - diff --git a/src/components/work/QuestionForm.astro b/src/components/work/QuestionForm.astro deleted file mode 100644 index 7ecf429a..00000000 --- a/src/components/work/QuestionForm.astro +++ /dev/null @@ -1,128 +0,0 @@ ---- -import Button from '@treeseed/ui/components/astro/forms/Button.astro'; -import Field from '@treeseed/ui/components/astro/forms/Field.astro'; -import FormActions from '@treeseed/ui/components/astro/forms/FormActions.astro'; -import Select from '@treeseed/ui/components/astro/forms/Select.astro'; -import TextInput from '@treeseed/ui/components/astro/forms/TextInput.astro'; -import Textarea from '@treeseed/ui/components/astro/forms/Textarea.astro'; -import MarkdownField from '@treeseed/ui/components/astro/app/controls/MarkdownField.astro'; -import ContentFieldHelp from '@treeseed/ui/components/astro/app/controls/ContentFieldHelp.astro'; -import { QUESTION_STATUS_OPTIONS, QUESTION_TYPE_OPTIONS } from '../../capabilities/questions.js'; -import { contentFieldHelp } from '../../lib/market/content-form-help.js'; -import type { QuestionFormViewModel } from '../../view-models/ui-foundation/questions.vm.js'; - -interface Props { - viewModel: QuestionFormViewModel; -} - -const { viewModel } = Astro.props as Props; -const question = viewModel.question; -const formId = viewModel.mode === 'create' ? 'question-create-form' : 'question-edit-form'; -const dataId = viewModel.mode === 'create' ? 'question-create-data' : 'question-edit-data'; -const submitLabel = viewModel.mode === 'create' ? 'Create question' : 'Save question'; -const typeOptions = QUESTION_TYPE_OPTIONS.filter((option) => option.value); -const statusOptions = QUESTION_STATUS_OPTIONS.filter((option) => option.value); -const fieldHelp = (fieldName: string) => contentFieldHelp(fieldName) ?? { label: fieldName, purpose: '' }; -const operationData = JSON.stringify({ - collection: 'questions', - selectedProjectId: viewModel.selectedProjectId, - slug: question?.slug ?? '', - mode: viewModel.mode, -}).replace(/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {submitLabel} - Cancel - - - - - - diff --git a/src/config.ts b/src/config.ts index 4af156f8..9ddac2c6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1 +1 @@ -export { createTreeseedTenantSite as createTreeseedAdminSite } from '@treeseed/core/config'; +export { createTenantSite as createAdminSite } from '@treeseed/core/config'; diff --git a/src/config.yaml b/src/config.yaml new file mode 100644 index 00000000..8ffce42b --- /dev/null +++ b/src/config.yaml @@ -0,0 +1,56 @@ +site: + logo: + src: /logo.svg + alt: TreeSeed Admin logo + name: TreeSeed Admin + statement: Grow what you know + siteUrl: https://admin.treeseed.dev + githubRepository: https://github.com/treeseed-ai/admin + discordLink: https://discord.gg/example + headerMenu: [] + footerMenu: + - label: Project + items: + - label: Repository + href: https://github.com/treeseed-ai/admin + summary: Private and real-time administration for TreeSeed teams, projects, capacity, and knowledge. + projectStage: Standalone management portal + projectStageDetail: Connects to the open TreeSeed API and TreeDX-backed R2 content runtime without Market composition. + forms: {} + emailNotifications: + contactRouting: {} + subscribeRecipients: [] + theme: + defaultScheme: fern + defaultMode: system + schemes: + fern: + light: + accent: "#4f7d4e" + accentStrong: "#2f5a35" + accentSoft: "#dcebd6" + dark: + accent: "#8bbb75" + accentStrong: "#b9e69e" + accentSoft: "#20351f" +models: + pages: + defaults: { pageLayout: article, stage: admin, audience: [] } + notes: + defaults: { author: TreeSeed Admin Team, draft: false, groupIds: [] } + questions: + defaults: { draft: false, groupIds: [] } + objectives: + defaults: { draft: false, groupIds: [] } + proposals: + defaults: { draft: false, groupIds: [] } + decisions: + defaults: { draft: false, groupIds: [] } + people: + defaults: { status: live, groupIds: [] } + agents: + defaults: { groupIds: [] } + books: + defaults: { groupIds: [] } + docs: + defaults: { groupIds: [] } diff --git a/src/content-config.ts b/src/content-config.ts index 7d618796..a5ad33e9 100644 --- a/src/content-config.ts +++ b/src/content-config.ts @@ -1 +1 @@ -export { createTreeseedTenantCollections as createTreeseedAdminCollections } from '@treeseed/core/content-config'; +export { createTenantCollections as createAdminCollections } from '@treeseed/core/content-config'; diff --git a/src/content.config.ts b/src/content.config.ts new file mode 100644 index 00000000..489d6b6e --- /dev/null +++ b/src/content.config.ts @@ -0,0 +1,7 @@ +import { fileURLToPath } from 'node:url'; + +process.env.TREESEED_TENANT_ROOT ??= fileURLToPath(new URL('../', import.meta.url)); + +const { createTenantCollections } = await import('@treeseed/core/content-config'); + +export const collections = createTenantCollections(); diff --git a/src/env.d.ts b/src/env.d.ts index 01a7ec03..e1ad952c 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,4 +1,5 @@ /// +declare module 'virtual:treeseed-source-update' { const updatedAt: string | null; export default updatedAt; } declare module 'astro:middleware' { import type { MiddlewareHandler } from 'astro'; @@ -19,14 +20,9 @@ declare module 'cloudflare:sockets' { ): Socket; } -declare module 'libsodium-wrappers-sumo' { - const sodium: any; - export default sodium; -} - declare namespace App { interface Locals { - runtime?: import('@treeseed/sdk/types/cloudflare').CloudflareRuntime; + runtime?: import('@treeseed/sdk/site-contracts/cloudflare').CloudflareRuntime; contentPreview?: import('@treeseed/sdk').EditorialPreviewTokenPayload | null; auth?: { session: { @@ -39,7 +35,7 @@ declare namespace App { authenticatedAt?: string | null; expiresAt?: string | null; }; - principal: import('@treeseed/sdk/remote').ApiPrincipal; + principal: import('@treeseed/sdk/site-contracts/catalog').ApiPrincipal; } | null; } } diff --git a/src/index.ts b/src/index.ts index 6542b035..586c9300 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,2 @@ export * from './routes.js'; export * from './commerce.js'; -export * from './secret-managers.js'; diff --git a/src/layouts/AppLayout.astro b/src/layouts/AppLayout.astro new file mode 100644 index 00000000..5c2832a1 --- /dev/null +++ b/src/layouts/AppLayout.astro @@ -0,0 +1,193 @@ +--- +import '@treeseed/ui/styles/tokens.css'; +import '@treeseed/ui/styles/theme.css'; +import '@treeseed/ui/styles/ui.css'; +import '@treeseed/ui/styles/forms.css'; +import '@treeseed/ui/styles/app-shell.css'; +import '@treeseed/ui/styles/app-controls.css'; +import '@treeseed/ui/styles/charts.css'; +import '@treeseed/ui/styles/account/forms.css'; +import '@treeseed/ui/styles/auth.css'; +import ProductShell from '@treeseed/ui/components/astro/shell/ProductShell.astro'; +import ShellIcon from '@treeseed/ui/components/astro/shell/navigation/ShellIcon.astro'; +import LiveDevelopmentIndicator from '../components/LiveDevelopmentIndicator.astro'; +import { AppearancePersistenceIsland } from '@treeseed/ui/components/react/progressive'; +import { resolveAuthenticatedThemePreference } from '../lib/auth/accounts/appearance'; +import { compileGuidedThemePalette } from '@treeseed/ui/theme'; +import { SITE_SLOGAN } from '@treeseed/ui/site-brand'; +import { resolveDevelopmentScene } from '@treeseed/ui/foundation'; +import { principalHasPlatformPermission } from '../lib/auth/support/rbac'; +import { createApiFacade, envValue } from '../lib/market/api-client'; +import { ensureCsrfToken } from '../lib/auth/support/csrf'; +import { loadRouteHelpContext } from '../lib/help/context'; + +interface TeamEntry { + id: string; + name: string; + slug?: string; + displayName?: string | null; + allowedActions?: { + edit?: boolean; + viewOverview?: boolean; + }; +} + +interface Props { + title: string; + description?: string; + currentPath: string; + teams: TeamEntry[]; + activeTeam?: TeamEntry | null; + contentOwnsPageHeader?: boolean; + timeZone?: string; +} + +const { + title, + description = 'Manage your account, teams, and active team.', + currentPath, + teams, + activeTeam = null, + contentOwnsPageHeader = false, + timeZone: suppliedTimeZone, +} = Astro.props as Props; + +const appearance = await resolveAuthenticatedThemePreference(Astro); +const api = createApiFacade(Astro); +const [personalThemes, loadedPreferences] = await Promise.all([ + api.personalThemes().catch(() => []), + api.accountPreferences().catch(() => ({ timeZone: suppliedTimeZone ?? 'UTC', realTimeUpdates: true, realTimePollingIntervalSeconds: 5 as const, updatedAt: '' })), +]); +const preferences = { ...loadedPreferences, ...(suppliedTimeZone ? { timeZone: suppliedTimeZone } : {}) }; +const customSchemes = Object.fromEntries(personalThemes.flatMap((theme) => { + try { return [[theme.schemeId, compileGuidedThemePalette(theme.palette, theme.baseScheme)]]; } catch { return []; } +})); +const themeConfig = { + schemes: customSchemes, + schemeNames: Object.fromEntries(personalThemes.map((theme) => [theme.schemeId, theme.name])), +}; +const csrfToken = ensureCsrfToken(Astro); +const teamOptions = teams.filter((team: TeamEntry & { status?: string }) => (team.status ?? 'active') === 'active').map((team) => ({ + id: team.id, + label: team.displayName ?? team.name ?? team.slug ?? team.id, +})); +const helpContext = await loadRouteHelpContext(Astro, Astro.url.pathname, activeTeam?.id); +const principal = api.currentPrincipal; +const canReadFeedback = principalHasPlatformPermission(principal, 'feedback:read:global'); +const feedbackContext = principal ? { + canonicalPath: `${Astro.url.pathname}${Astro.url.search}`, + title, + capabilityId: 'admin.feedback.submit', + shell: 'product' as const, + context: activeTeam ? 'team' as const : 'personal' as const, + teamId: activeTeam?.id, + identityLabel: principal.displayName ?? 'Current account', + teamLabel: activeTeam ? (activeTeam.displayName ?? activeTeam.name ?? activeTeam.slug ?? activeTeam.id) : undefined, + environment: (import.meta.env.MODE === 'production' ? 'production' : 'local') as 'local' | 'production', + submissionEndpoint: '/v1/feedback', + screenshotPolicy: 'optional' as const, + buildId: import.meta.env.PUBLIC_TREESEED_BUILD_ID, + revision: import.meta.env.PUBLIC_TREESEED_REVISION, + routePattern: Astro.url.pathname, + policy: 'authenticated' as const, + source: 'page' as const, +} : undefined; +const discussionContext = principal && activeTeam ? { + teamId: activeTeam.id, + identityLabel: principal.displayName ?? 'Current account', + endpoint: '/v1/discussions', + realtime: { endpoint: '/v1/session/events', enabled: false }, +} : undefined; +const reviewerCandidate = envValue(Astro.locals, 'TREESEED_REVIEWER_URL'); +const developmentScene = import.meta.env.DEV ? resolveDevelopmentScene(Astro.url.searchParams.get('devScene') ?? '') : undefined; +let reviewerUrl = ''; +try { + const parsed = new URL(reviewerCandidate); + if (parsed.protocol === 'http:' && ['127.0.0.1', 'localhost', '::1'].includes(parsed.hostname)) reviewerUrl = parsed.toString(); +} catch { reviewerUrl = ''; } +--- + + + + Active team + {teams.length > 0 ? ( + + + + + {!activeTeam ? Choose a team : null} + {teamOptions.map((team) => ( + {team.label} + ))} + + + + + + + ) : ( + + + Create team + + )} + + + + + + + + diff --git a/src/layouts/PublicLayout.astro b/src/layouts/PublicLayout.astro new file mode 100644 index 00000000..473bd6a7 --- /dev/null +++ b/src/layouts/PublicLayout.astro @@ -0,0 +1,67 @@ +--- +import '@treeseed/ui/styles/tokens.css'; +import '@treeseed/ui/styles/theme.css'; +import '@treeseed/ui/styles/ui.css'; +import '@treeseed/ui/styles/forms.css'; +import '@treeseed/ui/styles/app-shell.css'; +import '@treeseed/ui/styles/site.css'; +import '@treeseed/ui/styles/knowledge-profile.css'; +import PublicShell from '@treeseed/ui/components/astro/shell/PublicShell.astro'; +import PublicFooter from '@treeseed/ui/components/astro/shell/PublicFooter.astro'; +import { SITE_SLOGAN } from '@treeseed/ui/site-brand'; +import { resolveAnonymousThemePreference, resolveAuthenticatedThemePreference } from '../lib/auth/accounts/appearance'; +import { createApiFacade } from '../lib/market/api-client'; +import { loadRouteHelpContext } from '../lib/help/context'; + +interface Props { + title?: string; + description?: string; + currentPath?: string; + profilePage?: boolean; +} + +const { + title = 'TreeSeed', + description = 'TreeSeed public knowledge profiles and publication trails.', + currentPath = '/', + profilePage = false, +} = Astro.props as Props; +const isSignedIn = Boolean(Astro.locals.auth?.principal); +const appearance = isSignedIn + ? await resolveAuthenticatedThemePreference(Astro) + : resolveAnonymousThemePreference(Astro); +const timeZone = isSignedIn + ? (await createApiFacade(Astro).accountPreferences().catch(() => ({ timeZone: 'UTC' }))).timeZone + : 'UTC'; +const helpContext = await loadRouteHelpContext(Astro, currentPath, undefined, { + shell: 'public', + context: 'public', +}); +--- + + + {!profilePage ? ( + + ) : null} + + diff --git a/src/layouts/TreeseedAppLayout.astro b/src/layouts/TreeseedAppLayout.astro deleted file mode 100644 index 6c36472b..00000000 --- a/src/layouts/TreeseedAppLayout.astro +++ /dev/null @@ -1,160 +0,0 @@ ---- -import '@treeseed/ui/styles/tokens.css'; -import '@treeseed/ui/styles/theme.css'; -import '@treeseed/ui/styles/ui.css'; -import '@treeseed/ui/styles/forms.css'; -import '@treeseed/ui/styles/app-shell.css'; -import '@treeseed/ui/styles/app-controls.css'; -import '@treeseed/ui/styles/auth.css'; -import '@treeseed/ui/styles/operations.css'; -import '@treeseed/ui/styles/pie-allocation.css'; -import ProductShell from '@treeseed/ui/components/astro/shell/ProductShell.astro'; -import DeleteConfirmationModal from '@treeseed/ui/components/astro/app/controls/DeleteConfirmationModal.astro'; -import SensitiveDataUnlock from '@treeseed/ui/components/astro/app/sensitive/SensitiveDataUnlock.astro'; -import type { FeedbackContext, HelpContext } from '@treeseed/ui'; -import { resolveAuthenticatedThemePreference } from '../lib/auth/appearance'; - -interface TeamEntry { - id: string; - name: string; - slug?: string; - displayName?: string | null; -} - -interface Props { - title: string; - description?: string; - currentPath: string; - teams: TeamEntry[]; - activeTeam?: TeamEntry | null; - showSensitiveUnlock?: boolean; - helpContext?: HelpContext; - feedbackContext?: FeedbackContext; -} - -const { - title, - description = 'Set up teams, hosts, projects, capacity, work, and knowledge.', - currentPath, - teams, - activeTeam = null, - showSensitiveUnlock: forceSensitiveUnlock = false, - helpContext, - feedbackContext, -} = Astro.props as Props; - -const railItems = [ - { label: 'Start', href: '/app/' }, - { label: 'Services', href: '/app/services' }, - { label: 'Projects', href: '/app/projects' }, - { label: 'Capacity', href: '/app/capacity/allocation' }, - { label: 'Work', href: '/app/work' }, - { label: 'Knowledge', href: '/app/knowledge' }, - { label: 'Market', href: '/market/' }, - { label: 'Cart', href: '/cart' }, - { label: 'Service requests', href: '/services/new' }, - { label: 'Seller operations', href: '/app/market/seller' }, -]; - -const appearance = await resolveAuthenticatedThemePreference(Astro); -const quickActions = [ - activeTeam - ? { label: 'New project', href: '/app/projects/new', variant: 'primary' as const } - : { label: 'New team', href: '/app/teams/new', variant: 'primary' as const }, - { label: 'Browse market', href: '/market/', variant: 'secondary' as const }, -]; -const accountActions = [ - { label: 'Account', href: '/app/account', variant: 'secondary' as const }, - { label: 'Sign out', href: '/v1/auth/logout?returnTo=/', variant: 'secondary' as const, reload: true }, -]; -const teamOptions = teams.map((team) => ({ - id: team.id, - label: team.displayName ?? team.name ?? team.slug ?? team.id, -})); -const sensitiveUnlockPaths = [ - '/app/hosts', - '/app/projects/new', - '/app/capacity/providers/new', -]; -const routePath = Astro.url.pathname; -const showSensitiveUnlock = sensitiveUnlockPaths.some((path) => ( - currentPath === path - || currentPath.startsWith(`${path}/`) - || routePath === path - || routePath.startsWith(`${path}/`) -)) || forceSensitiveUnlock; ---- - - - - Team - {teams.length > 0 ? ( - - - - {teamOptions.map((team) => ( - {team.label} - ))} - - - Manage - - ) : ( - Create team - )} - - {showSensitiveUnlock ? : null} - - {showSensitiveUnlock ? : null} - - - - - - diff --git a/src/layouts/TreeseedOperationalMarketLayout.astro b/src/layouts/TreeseedOperationalMarketLayout.astro deleted file mode 100644 index 36a8f5bc..00000000 --- a/src/layouts/TreeseedOperationalMarketLayout.astro +++ /dev/null @@ -1,40 +0,0 @@ ---- -import TreeseedAppLayout from './TreeseedAppLayout.astro'; -import type { FeedbackContext, HelpContext } from '@treeseed/ui'; -import { loadAppContext } from '../view-models/app-access.js'; - -interface Props { - title?: string; - description?: string; - currentPath?: string; - helpContext?: HelpContext; - feedbackContext?: FeedbackContext; -} - -const { - title = 'TreeSeed Market', - description = 'Operational TreeSeed market and team commerce surfaces.', - currentPath = Astro.url.pathname, - helpContext, - feedbackContext, -} = Astro.props as Props; - -if (!Astro.locals.auth?.principal) { - const returnTo = `${Astro.url.pathname}${Astro.url.search}`; - return Astro.redirect(`/auth/sign-in?returnTo=${encodeURIComponent(returnTo)}`); -} - -const context = await loadAppContext(Astro); ---- - - - - diff --git a/src/layouts/TreeseedPublicLayout.astro b/src/layouts/TreeseedPublicLayout.astro deleted file mode 100644 index ab517caf..00000000 --- a/src/layouts/TreeseedPublicLayout.astro +++ /dev/null @@ -1,93 +0,0 @@ ---- -import '@treeseed/ui/styles/tokens.css'; -import '@treeseed/ui/styles/theme.css'; -import '@treeseed/ui/styles/ui.css'; -import '@treeseed/ui/styles/forms.css'; -import '@treeseed/ui/styles/app-shell.css'; -import '@treeseed/ui/styles/site.css'; -import '@treeseed/ui/styles/market.css'; -import PublicShell from '@treeseed/ui/components/astro/shell/PublicShell.astro'; -import PublicFooter from '@treeseed/ui/components/astro/shell/PublicFooter.astro'; -import ShellIconLink from '@treeseed/ui/components/astro/shell/ShellIconLink.astro'; -import type { FeedbackContext, HelpContext } from '@treeseed/ui'; -import { resolveAnonymousThemePreference, resolveAuthenticatedThemePreference } from '../lib/auth/appearance'; - -interface NavItem { - label: string; - href: string; -} - -interface Props { - title?: string; - description?: string; - currentPath?: string; - helpContext?: HelpContext; - feedbackContext?: FeedbackContext; -} - -const { - title = 'TreeSeed', - description = 'Launch, guide, release, and publish knowledge hubs with your team and your agents.', - currentPath = '/', - helpContext, - feedbackContext, -} = Astro.props as Props; - -const navItems: NavItem[] = [ - { label: 'Home', href: '/' }, - { label: 'Resources', href: '/market/' }, - { label: 'Workflow Imports', href: '/market/templates/' }, - { label: 'Knowledge Imports', href: '/market/knowledge-packs/' }, -]; - -const isSignedIn = Boolean(Astro.locals.auth?.principal); -const appearance = isSignedIn - ? await resolveAuthenticatedThemePreference(Astro) - : resolveAnonymousThemePreference(Astro); -const actions = isSignedIn - ? [] - : [ - { label: 'Sign in', href: '/auth/sign-in', variant: 'ghost' as const }, - ]; ---- - - - - - - - - diff --git a/src/lib/accounts/navigation.ts b/src/lib/accounts/navigation.ts new file mode 100644 index 00000000..743abf67 --- /dev/null +++ b/src/lib/accounts/navigation.ts @@ -0,0 +1,7 @@ +export const ACCOUNT_SECTIONS = [ + { id: 'identity', label: 'Identity', href: '/app/account' }, + { id: 'sessions', label: 'Sessions', href: '/app/account/sessions' }, + { id: 'notifications', label: 'Notifications', href: '/app/account/notifications' }, + { id: 'appearance', label: 'Appearance', href: '/app/account/appearance' }, + { id: 'delete', label: 'Delete', href: '/app/account/delete' }, +] as const; diff --git a/src/lib/agents/client-action-executor.ts b/src/lib/agents/client-action-executor.ts new file mode 100644 index 00000000..354d6a85 --- /dev/null +++ b/src/lib/agents/client-action-executor.ts @@ -0,0 +1,40 @@ +type ActionRow={ id:string;kind:string;payload_json:string }; +type ActionEvent=(name:string,detail:Record)=>void; +const capabilities=['navigate','reveal-resource','set-view-filter','populate-draft','present-confirmation']; +function object(value:unknown){return value&&typeof value==='object'&&!Array.isArray(value)?value as Record:{};} +function parse(value:string){try{return object(JSON.parse(value));}catch{return {};}} +function event(name:string,detail:Record){window.dispatchEvent(new CustomEvent(name,{detail}));} +export function resolveClientAction(action:ActionRow,emit:ActionEvent){ + const payload=parse(action.payload_json); + if(action.kind==='navigate'){ + const path=typeof payload.path==='string'?payload.path:''; + if(!path.startsWith('/app/'))throw new Error('Navigation is restricted to authenticated application routes.'); + return {path}; + } + if(action.kind==='reveal-resource'){emit('treeseed:client-action:reveal-resource',payload);return payload;} + if(action.kind==='set-view-filter'){emit('treeseed:client-action:set-view-filter',payload);return payload;} + if(action.kind==='populate-draft'){emit('treeseed:client-action:populate-draft',payload);return payload;} + if(action.kind==='present-confirmation'){emit('treeseed:client-action:present-confirmation',payload);return payload;} + throw new Error('Unsupported semantic client action.'); +} +async function execute(action:ActionRow){return resolveClientAction(action,event);} +async function json(url:string,init?:RequestInit){const response=await fetch(url,{...init,credentials:'same-origin',headers:{accept:'application/json','content-type':'application/json',...(init?.headers??{})}});if(!response.ok)throw new Error(`Client action API failed with HTTP ${response.status}.`);return response.json();} + +export function startClientActionExecutor(){ + const host=document.querySelector('[data-client-action-project]'); const projectId=host?.dataset.clientActionProject??location.pathname.match(/^\/app\/projects\/([^/]+)/u)?.[1]; + if(!projectId)return()=>undefined; + const key=`treeseed:client-session:${projectId}`; const sessionId=sessionStorage.getItem(key)??crypto.randomUUID(); sessionStorage.setItem(key,sessionId); + let stopped=false; let timer:number|undefined; + const register=()=>json('/v1/client-sessions',{method:'POST',body:JSON.stringify({sessionId,projectId,route:`${location.pathname}${location.search}`,capabilities})}); + const result=(action:ActionRow,status:'completed'|'rejected'|'failed',detail:Record)=>json(`/v1/client-sessions/${encodeURIComponent(sessionId)}/actions/${encodeURIComponent(action.id)}/result`,{method:'POST',body:JSON.stringify({status,detail})}); + const tick=async()=>{ + try{ + await json(`/v1/client-sessions/${encodeURIComponent(sessionId)}/heartbeat`,{method:'POST',body:'{}'}).catch(register); + const envelope=await json(`/v1/client-sessions/${encodeURIComponent(sessionId)}/actions`); const actions=Array.isArray(envelope.payload)?envelope.payload as ActionRow[]:[]; + for(const action of actions){try{const detail=object(await execute(action));await result(action,'completed',detail);if(action.kind==='navigate'&&typeof detail.path==='string')window.location.assign(new URL(detail.path,window.location.origin));}catch(error){await result(action,'failed',{message:error instanceof Error?error.message:String(error)});}} + }catch{/* Heartbeat expiry makes requests unavailable without blocking the provider. */} + if(!stopped)timer=window.setTimeout(tick,5_000); + }; + void register().then(tick).catch(()=>{timer=window.setTimeout(tick,5_000);}); + return()=>{stopped=true;if(timer)window.clearTimeout(timer);}; +} diff --git a/src/lib/auth/account.ts b/src/lib/auth/accounts/account.ts similarity index 74% rename from src/lib/auth/account.ts rename to src/lib/auth/accounts/account.ts index 4987c624..65999555 100644 --- a/src/lib/auth/account.ts +++ b/src/lib/auth/accounts/account.ts @@ -4,8 +4,8 @@ import { normalizeUsername, validateUsername, type UsernameValidationResult, -} from './profile-validation.ts'; -import { DELETE_ACCOUNT_CONFIRMATION } from './delete-confirmation.ts'; +} from '../support/profile-validation.ts'; +import { DELETE_ACCOUNT_CONFIRMATION } from '../support/delete-confirmation.ts'; export { RESERVED_USERNAMES, composeDisplayNameFromParts, normalizeUsername, validateUsername }; export type { UsernameValidationResult }; @@ -39,16 +39,9 @@ export interface PublicUserProfile { id: string; username: string; displayName: string | null; - email: string | null; image: string | null; joinedAt: string; }; - activity: { - teams: Array<{ id: string; slug: string; name: string; createdAt?: string }>; - projects: Array<{ id: string; teamId: string; slug: string; name: string; description?: string | null; createdAt?: string }>; - catalogItems: Array<{ id: string; teamId: string; kind: string; slug: string; title: string; summary?: string | null; visibility?: string }>; - knowledgePacks: Array<{ id: string; teamId: string; slug: string; name: string; summary?: string | null; visibility?: string }>; - }; } function normalizeOptionalString(value: FormDataEntryValue | null) { diff --git a/src/lib/auth/appearance.ts b/src/lib/auth/accounts/appearance.ts similarity index 66% rename from src/lib/auth/appearance.ts rename to src/lib/auth/accounts/appearance.ts index 075eeece..1f4ee715 100644 --- a/src/lib/auth/appearance.ts +++ b/src/lib/auth/accounts/appearance.ts @@ -1,11 +1,13 @@ import { + normalizeAppearancePreference, normalizeThemePreference, + type AppearancePreference, type ThemePreference, } from '@treeseed/ui/theme'; import type { APIContext } from 'astro'; -export const TREESEED_COLOR_SCHEME_COOKIE = 'treeseed_color_scheme'; -export const TREESEED_THEME_MODE_COOKIE = 'treeseed_theme_mode'; +export const COLOR_SCHEME_COOKIE = 'treeseed_color_scheme'; +export const THEME_MODE_COOKIE = 'treeseed_theme_mode'; export type AnonymousAppearanceContext = { url: URL; @@ -18,6 +20,10 @@ export type AnonymousAppearanceContext = { export type AppearanceContext = AnonymousAppearanceContext & Pick; +export function shouldReloadAppearancePage(pathname: string, persisted: boolean) { + return persisted && pathname.replace(/\/+$/u, '') === '/app/account/appearance'; +} + export function resolveAnonymousThemePreference( context: AnonymousAppearanceContext, form?: FormData, @@ -25,10 +31,10 @@ export function resolveAnonymousThemePreference( return normalizeThemePreference({ scheme: form?.get('colorScheme') ?? context.url.searchParams.get('colorScheme') - ?? context.cookies.get(TREESEED_COLOR_SCHEME_COOKIE)?.value, + ?? context.cookies.get(COLOR_SCHEME_COOKIE)?.value, mode: form?.get('themeMode') ?? context.url.searchParams.get('themeMode') - ?? context.cookies.get(TREESEED_THEME_MODE_COOKIE)?.value, + ?? context.cookies.get(THEME_MODE_COOKIE)?.value, }); } @@ -46,21 +52,21 @@ export function setAnonymousThemeCookies( preference: ThemePreference, ) { const options = anonymousThemeCookieOptions(context); - context.cookies.set(TREESEED_COLOR_SCHEME_COOKIE, preference.scheme, options); - context.cookies.set(TREESEED_THEME_MODE_COOKIE, preference.mode, options); + context.cookies.set(COLOR_SCHEME_COOKIE, preference.scheme, options); + context.cookies.set(THEME_MODE_COOKIE, preference.mode, options); } -function appearanceFromPrincipal(context: Pick): ThemePreference | null { +function appearanceFromPrincipal(context: Pick): AppearancePreference | null { const principal = context.locals.auth?.principal; const appearance = principal?.metadata?.appearance; if (!appearance || typeof appearance !== 'object') return null; - return normalizeThemePreference(appearance); + return normalizeAppearancePreference(appearance); } -export function themePreferenceFromPrincipal(principal: { metadata?: Record | null } | null | undefined): ThemePreference | null { +export function themePreferenceFromPrincipal(principal: { metadata?: Record | null } | null | undefined): AppearancePreference | null { const appearance = principal?.metadata?.appearance; if (!appearance || typeof appearance !== 'object') return null; - return normalizeThemePreference(appearance); + return normalizeAppearancePreference(appearance); } export function setPrincipalThemeCookies( @@ -73,19 +79,19 @@ export function setPrincipalThemeCookies( return preference; } -export async function resolveAuthenticatedThemePreference(context: AppearanceContext): Promise { - return appearanceFromPrincipal(context) ?? resolveAnonymousThemePreference(context); +export async function resolveAuthenticatedThemePreference(context: AppearanceContext): Promise { + return appearanceFromPrincipal(context) ?? normalizeAppearancePreference(resolveAnonymousThemePreference(context)); } export async function resolveUserThemePreference( context: AppearanceContext, userId: string, -): Promise { +): Promise { const principal = context.locals.auth?.principal; if (principal?.id === userId) { - return appearanceFromPrincipal(context) ?? resolveAnonymousThemePreference(context); + return appearanceFromPrincipal(context) ?? normalizeAppearancePreference(resolveAnonymousThemePreference(context)); } - return resolveAnonymousThemePreference(context); + return normalizeAppearancePreference(resolveAnonymousThemePreference(context)); } export async function setUserThemeCookies( diff --git a/src/lib/auth/application-session.ts b/src/lib/auth/application-session.ts new file mode 100644 index 00000000..86ef3d24 --- /dev/null +++ b/src/lib/auth/application-session.ts @@ -0,0 +1,65 @@ +import type { APIContext } from 'astro'; +import { importPKCS8 } from 'jose'; +import { createApplicationSession, createWorkloadCredentials, discoverResourceAuthorization, discoverSigningKeys } from '@treeseed/identity'; +import { identityEndpointSchema } from '@treeseed/sdk/identity'; +import { REMOTE_CONTRACT_HEADER, REMOTE_CONTRACT_VERSION } from '@treeseed/sdk/site-contracts/catalog'; + +type Context = Pick; +type Session = ReturnType; +const requestTokens = new WeakMap(); +let cached: { fingerprint: string; session: Promise } | undefined; + +/** Deployment supplies this independent asymmetric workload key through its + * protected runtime configuration. It is never a browser or vault login key. */ +function setting(context: Context, name: string) { + const env = context.locals.runtime?.env as Record | undefined; + const value = env?.[name] ?? globalThis.process?.env?.[name]; + return typeof value === 'string' ? value.trim() : ''; +} + +export function apiResource(context: Context) { + return identityEndpointSchema.parse(setting(context, 'TREESEED_API_BASE_URL')).replace(/\/$/u, ''); +} + +export function identityAccountUrl(context: Context) { + const issuer = new URL(identityEndpointSchema.parse(setting(context, 'TREESEED_IDENTITY_ISSUER'))); + const account = new URL(identityEndpointSchema.parse(setting(context, 'TREESEED_IDENTITY_ACCOUNT_URL'))); + if (account.origin !== issuer.origin) throw new Error('Identity management must use the configured authority.'); + return account.href; +} + +export async function applicationSession(context: Context): Promise { + const configuration = { resource: apiResource(context), issuer: setting(context, 'TREESEED_IDENTITY_ISSUER'), + origin: identityEndpointSchema.parse(setting(context, 'TREESEED_SITE_URL')), + clientId: setting(context, 'TREESEED_IDENTITY_WORKLOAD_CLIENT_ID'), key: setting(context, 'TREESEED_IDENTITY_WORKLOAD_PRIVATE_KEY') }; + if (new URL(configuration.origin).pathname !== '/' || !configuration.clientId || !configuration.key) throw new Error('Identity application configuration is required.'); + const fingerprint = [...new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(JSON.stringify(configuration))))] + .map(value => value.toString(16).padStart(2, '0')).join(''); + if (cached?.fingerprint === fingerprint) return cached.session; + const session = (async () => { + const authority = await discoverResourceAuthorization({ resource: configuration.resource, + ...(configuration.issuer ? { issuer: configuration.issuer } : {}), transport: fetch }); + const workload = await createWorkloadCredentials({ issuer: authority.issuer, clientId: configuration.clientId, + privateKey: await importPKCS8(configuration.key, 'RS256'), resources: [authority.resource], + verificationKey: await discoverSigningKeys({ issuer: authority.issuer, transport: fetch }), profile: 'keycloak', transport: fetch, + resolvePrincipal: async identity => ({ principalId: identity.subject, kind: 'service', clientId: configuration.clientId }) }); + return createApplicationSession({ issuer: authority.issuer, resource: authority.resource, + callbackUrl: new URL('/auth/callback', configuration.origin).href, afterLogin: '/app/', cookieName: '__Host-treeseed-admin', + credentials: { token: async request => (await workload.credentials(request)).accessToken }, transport: fetch }); + })(); + cached = { fingerprint, session }; + try { return await session; } catch { if (cached?.fingerprint === fingerprint) cached = undefined; throw new Error('Identity sign-in is unavailable.'); } +} + +/** A request-local, server-only token, not a serializable Astro locals field. */ +export function setRequestCredential(context: Context, value: { resource: string; accessToken: string }) { + if (value.resource !== apiResource(context)) throw new Error('API credential resource mismatch.'); + requestTokens.set(context.locals, value); +} + +export function apiRequestHeaders(context: Context) { + const token = requestTokens.get(context.locals); + if (token && token.resource !== apiResource(context)) throw new Error('API credential resource mismatch.'); + return new Headers({ accept: 'application/json', [REMOTE_CONTRACT_HEADER]: String(REMOTE_CONTRACT_VERSION), + ...(token ? { authorization: `Bearer ${token.accessToken}` } : {}) }); +} diff --git a/src/lib/auth/config.ts b/src/lib/auth/config.ts deleted file mode 100644 index c3e1cd90..00000000 --- a/src/lib/auth/config.ts +++ /dev/null @@ -1,191 +0,0 @@ -import type { APIContext } from 'astro'; -import type { CloudflareRuntime } from '@treeseed/sdk/types/cloudflare'; - -export const WEB_SESSION_COOKIE = 'ts_session'; -export const WEB_CSRF_COOKIE = 'ts_csrf'; -const DEFAULT_WEB_SESSION_TTL_SECONDS = 7 * 24 * 60 * 60; -const DEFAULT_EMAIL_TOKEN_TTL_SECONDS = 60 * 60; -const DEFAULT_LOCAL_SMTP_HOST = '127.0.0.1'; -const DEFAULT_LOCAL_SMTP_PORT = 1025; -const DEFAULT_LOCAL_AUTH_EMAIL_FROM = 'Treeseed Market '; -export const BETTER_AUTH_BASE_PATH = '/v1/auth'; -const AUTH_MODES = new Set(['internal-first', 'internal-only', 'providers-only']); -const INTERNAL_SIGNUP_MODES = new Set(['open', 'invite', 'admin']); -const LOCAL_AUTH_HOSTNAMES = new Set(['localhost', '127.0.0.1', '0.0.0.0', '::1', '[::1]']); - -type RuntimeEnv = CloudflareRuntime['env']; - -function runtimeEnv(context?: Pick) { - return ((context?.locals as App.Locals | undefined)?.runtime as CloudflareRuntime | undefined)?.env; -} - -function envValue(name: string, env?: RuntimeEnv) { - const runtime = env as Record | undefined; - const runtimeValue = runtime?.[name]; - if (typeof runtimeValue === 'string' && runtimeValue.trim()) { - return runtimeValue.trim(); - } - const processValue = (globalThis as { process?: { env?: Record } }).process?.env?.[name]; - return typeof processValue === 'string' && processValue.trim() ? processValue.trim() : ''; -} - -function firstEnvValue(env: RuntimeEnv | undefined, ...names: string[]) { - for (const name of names) { - const value = envValue(name, env); - if (value) return value; - } - return ''; -} - -function parseIntEnv(name: string, fallback: number, env?: RuntimeEnv) { - const value = envValue(name, env); - if (!value) return fallback; - const parsed = Number.parseInt(value, 10); - return Number.isFinite(parsed) ? parsed : fallback; -} - -function parseBooleanEnv(name: string, fallback: boolean, env?: RuntimeEnv) { - const value = envValue(name, env).toLowerCase(); - if (!value) return fallback; - return ['1', 'true', 'yes', 'on'].includes(value) - ? true - : ['0', 'false', 'no', 'off'].includes(value) - ? false - : fallback; -} - -function parseEnumEnv(name: string, allowed: Set, fallback: T, env?: RuntimeEnv) { - const value = envValue(name, env) as T; - return allowed.has(value) ? value : fallback; -} - -function normalizeUrl(value: string, fallback: string) { - try { - const url = new URL(value || fallback); - url.search = ''; - url.hash = ''; - return url; - } catch { - return new URL(fallback); - } -} - -function isLocalUrl(value: string) { - try { - return LOCAL_AUTH_HOSTNAMES.has(new URL(value).hostname); - } catch { - return false; - } -} - -export function normalizeSiteBaseUrl(value: string, fallback = 'http://127.0.0.1:4321') { - const url = normalizeUrl(value, fallback); - const pathname = url.pathname.replace(/\/+$/u, ''); - url.pathname = pathname.endsWith(BETTER_AUTH_BASE_PATH) - ? pathname.slice(0, -BETTER_AUTH_BASE_PATH.length) || '/' - : pathname || '/'; - return url.pathname === '/' ? url.origin : `${url.origin}${url.pathname}`; -} - -export function normalizeBetterAuthBaseUrl(value: string, fallback = 'http://127.0.0.1:4321') { - const url = normalizeUrl(value, fallback); - const pathname = url.pathname.replace(/\/+$/u, ''); - url.pathname = pathname.endsWith(BETTER_AUTH_BASE_PATH) ? pathname : BETTER_AUTH_BASE_PATH; - return `${url.origin}${url.pathname}`; -} - -export function localAuthCanonicalRedirectUrl(requestUrl: URL, configuredSiteBaseUrl: string) { - const canonical = normalizeUrl(configuredSiteBaseUrl, 'http://127.0.0.1:4321'); - if (!isLocalUrl(requestUrl.href) || !isLocalUrl(canonical.href)) return null; - if ( - requestUrl.protocol === canonical.protocol - && requestUrl.hostname === canonical.hostname - && requestUrl.port === canonical.port - ) { - return null; - } - const redirectUrl = new URL(`${requestUrl.pathname}${requestUrl.search}`, canonical.origin); - return redirectUrl; -} - -export function getSiteAuthConfig(context?: Pick & Partial>) { - const env = runtimeEnv(context); - const authMode = parseEnumEnv('TREESEED_AUTH_MODE', AUTH_MODES, 'internal-first', env); - const internalSignup = parseEnumEnv('TREESEED_AUTH_INTERNAL_SIGNUP', INTERNAL_SIGNUP_MODES, 'open', env); - const requestOrigin = context?.url?.origin ?? ''; - const configuredSiteBaseUrl = envValue('TREESEED_SITE_URL', env) || envValue('BETTER_AUTH_URL', env) || requestOrigin || 'http://127.0.0.1:4321'; - const siteBaseUrl = normalizeSiteBaseUrl(configuredSiteBaseUrl); - const betterAuthBaseUrl = normalizeBetterAuthBaseUrl(envValue('BETTER_AUTH_URL', env) || siteBaseUrl); - const localAuthEmail = isLocalUrl(siteBaseUrl) || isLocalUrl(betterAuthBaseUrl); - const localMailpitHost = envValue('TREESEED_MAILPIT_SMTP_HOST', env) || DEFAULT_LOCAL_SMTP_HOST; - const localMailpitPort = parseIntEnv('TREESEED_MAILPIT_SMTP_PORT', DEFAULT_LOCAL_SMTP_PORT, env); - const authEmailFrom = firstEnvValue(env, 'TREESEED_AUTH_EMAIL_FROM', 'TREESEED_SMTP_FROM') - || (localAuthEmail ? DEFAULT_LOCAL_AUTH_EMAIL_FROM : ''); - return { - authMode, - internalAuthEnabled: authMode !== 'providers-only', - internalSignup, - internalSignupEnabled: authMode !== 'providers-only' && internalSignup === 'open', - providersEnabled: authMode !== 'internal-only', - emailLinkingEnabled: parseBooleanEnv('TREESEED_AUTH_EMAIL_LINKING', true, env), - allowMemoryAuthDb: parseBooleanEnv('TREESEED_AUTH_ALLOW_MEMORY_DB', false, env), - betterAuthSecret: envValue('TREESEED_BETTER_AUTH_SECRET', env) || 'treeseed-local-better-auth-secret-minimum-32-characters', - siteBaseUrl, - betterAuthBaseUrl, - apiServiceId: firstEnvValue(env, 'TREESEED_WEB_SERVICE_ID', 'TREESEED_API_WEB_SERVICE_ID') || 'web', - apiServiceSecret: firstEnvValue(env, 'TREESEED_WEB_SERVICE_SECRET', 'TREESEED_API_WEB_SERVICE_SECRET') || 'treeseed-web-service-dev-secret', - apiAssertionSecret: firstEnvValue(env, 'TREESEED_WEB_ASSERTION_SECRET', 'TREESEED_API_WEB_ASSERTION_SECRET') || 'treeseed-web-assertion-dev-secret', - csrfSecret: envValue('TREESEED_WEB_CSRF_SECRET', env) || 'treeseed-web-csrf-dev-secret', - sessionTtlSeconds: parseIntEnv('TREESEED_WEB_SESSION_TTL', DEFAULT_WEB_SESSION_TTL_SECONDS, env), - passwordResetTtlSeconds: parseIntEnv('TREESEED_AUTH_PASSWORD_RESET_TTL', DEFAULT_EMAIL_TOKEN_TTL_SECONDS, env), - emailVerificationTtlSeconds: parseIntEnv('TREESEED_AUTH_EMAIL_VERIFICATION_TTL', DEFAULT_EMAIL_TOKEN_TTL_SECONDS, env), - emailVerificationEnabled: parseBooleanEnv('TREESEED_AUTH_EMAIL_VERIFICATION_ENABLED', true, env), - authEmail: { - host: localAuthEmail ? localMailpitHost : envValue('TREESEED_SMTP_HOST', env), - port: localAuthEmail ? localMailpitPort : parseIntEnv('TREESEED_SMTP_PORT', 465, env), - username: localAuthEmail ? '' : envValue('TREESEED_SMTP_USERNAME', env), - password: localAuthEmail ? '' : envValue('TREESEED_SMTP_PASSWORD', env), - from: authEmailFrom, - replyTo: firstEnvValue(env, 'TREESEED_AUTH_EMAIL_REPLY_TO', 'TREESEED_SMTP_REPLY_TO'), - secure: localAuthEmail ? '' : envValue('TREESEED_SMTP_SECURE', env), - }, - providers: { - github: { - clientId: envValue('TREESEED_AUTH_GITHUB_CLIENT_ID', env), - clientSecret: envValue('TREESEED_AUTH_GITHUB_CLIENT_SECRET', env), - }, - google: { - clientId: envValue('TREESEED_AUTH_GOOGLE_CLIENT_ID', env), - clientSecret: envValue('TREESEED_AUTH_GOOGLE_CLIENT_SECRET', env), - }, - microsoft: { - clientId: envValue('TREESEED_AUTH_MICROSOFT_CLIENT_ID', env), - clientSecret: envValue('TREESEED_AUTH_MICROSOFT_CLIENT_SECRET', env), - }, - apple: { - clientId: envValue('TREESEED_AUTH_APPLE_CLIENT_ID', env), - clientSecret: envValue('TREESEED_AUTH_APPLE_CLIENT_SECRET', env), - }, - }, - }; -} - -export function webCookieOptions(requestUrl: URL, maxAge: number) { - return { - httpOnly: true, - path: '/', - sameSite: 'lax' as const, - secure: requestUrl.protocol === 'https:', - maxAge, - }; -} - -export function csrfCookieOptions(requestUrl: URL, maxAge: number) { - return { - httpOnly: false, - path: '/', - sameSite: 'lax' as const, - secure: requestUrl.protocol === 'https:', - maxAge, - }; -} diff --git a/src/lib/auth/configuration/config.ts b/src/lib/auth/configuration/config.ts new file mode 100644 index 00000000..a4784b99 --- /dev/null +++ b/src/lib/auth/configuration/config.ts @@ -0,0 +1,5 @@ +export const WEB_CSRF_COOKIE = 'ts_csrf'; + +export function csrfCookieOptions(requestUrl: URL, maxAge: number) { + return { httpOnly: false, path: '/', sameSite: 'lax' as const, secure: requestUrl.protocol === 'https:', maxAge }; +} diff --git a/src/lib/auth/email-confirmation.ts b/src/lib/auth/email-confirmation.ts deleted file mode 100644 index c1f963c1..00000000 --- a/src/lib/auth/email-confirmation.ts +++ /dev/null @@ -1,173 +0,0 @@ -import React from 'react'; -import { render } from '@react-email/render'; -import type { APIContext } from 'astro'; -import { sendAuthEmail } from './email.ts'; - -interface EmailConfirmationInput { - email: string; - displayName?: string | null; - confirmationUrl: string; - expiresInSeconds: number; -} - -const colors = { - page: '#f6f7f2', - ink: '#17211b', - muted: '#526052', - border: '#d9ded4', - card: '#ffffff', - green: '#2f6f4e', - gold: '#d9a441', -}; - -function expiryLabel(seconds: number) { - const minutes = Math.max(1, Math.round(seconds / 60)); - return minutes === 1 ? '1 minute' : `${minutes} minutes`; -} - -function EmailConfirmation({ displayName, confirmationUrl, expiresInSeconds }: { - displayName: string; - confirmationUrl: string; - expiresInSeconds: number; -}) { - return React.createElement('html', { lang: 'en' }, - React.createElement('body', { - style: { - margin: 0, - backgroundColor: colors.page, - color: colors.ink, - fontFamily: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif', - }, - }, - React.createElement('div', { style: { padding: '32px 18px' } }, - React.createElement('div', { - style: { - maxWidth: 560, - margin: '0 auto', - backgroundColor: colors.card, - border: `1px solid ${colors.border}`, - borderRadius: 8, - overflow: 'hidden', - boxShadow: '0 18px 40px rgba(19, 31, 22, 0.08)', - }, - }, - React.createElement('div', { - style: { - padding: '28px 32px 22px', - backgroundColor: '#edf2e9', - borderBottom: `1px solid ${colors.border}`, - }, - }, - React.createElement('div', { - style: { - display: 'inline-block', - padding: '5px 9px', - borderRadius: 999, - backgroundColor: '#fff7df', - color: '#6e4c0d', - fontSize: 12, - fontWeight: 700, - letterSpacing: 0, - marginBottom: 16, - }, - }, 'Confirm your email'), - React.createElement('h1', { - style: { - margin: 0, - fontSize: 28, - lineHeight: '34px', - fontWeight: 800, - letterSpacing: 0, - }, - }, `Finish creating your Treeseed Market account, ${displayName}.`), - React.createElement('p', { - style: { - margin: '12px 0 0', - color: colors.muted, - fontSize: 15, - lineHeight: '23px', - }, - }, `This link expires in ${expiryLabel(expiresInSeconds)}.`)), - React.createElement('div', { style: { padding: '28px 32px 32px' } }, - React.createElement('p', { - style: { - margin: '0 0 18px', - color: colors.muted, - fontSize: 15, - lineHeight: '24px', - }, - }, 'Confirm this email address to activate your account and continue to Treeseed Market.'), - React.createElement('a', { - href: confirmationUrl, - style: { - display: 'inline-block', - backgroundColor: colors.green, - color: '#ffffff', - textDecoration: 'none', - borderRadius: 6, - padding: '12px 18px', - fontWeight: 800, - fontSize: 14, - }, - }, 'Confirm email'), - React.createElement('div', { - style: { - marginTop: 24, - paddingTop: 20, - borderTop: `1px solid ${colors.border}`, - }, - }, - React.createElement('p', { - style: { - margin: 0, - color: colors.muted, - fontSize: 13, - lineHeight: '20px', - }, - }, 'If the button does not work, open this link in your browser:'), - React.createElement('p', { - style: { - margin: '6px 0 0', - color: colors.green, - fontSize: 13, - lineHeight: '20px', - wordBreak: 'break-all', - }, - }, confirmationUrl)), - React.createElement('p', { - style: { - margin: '24px 0 0', - color: colors.muted, - fontSize: 12, - lineHeight: '18px', - }, - }, 'You are receiving this because this email address was used to create a Treeseed Market account.')))))); -} - -function firstName(value: string) { - return value.trim().split(/\s+/u)[0] || value; -} - -export async function sendEmailConfirmation( - context: Pick | undefined, - input: EmailConfirmationInput, -) { - const email = input.email.trim(); - if (!email) return; - const displayName = firstName(input.displayName?.trim() || email.split('@')[0] || 'there'); - const element = React.createElement(EmailConfirmation, { - displayName, - confirmationUrl: input.confirmationUrl, - expiresInSeconds: input.expiresInSeconds, - }); - const [html, text] = await Promise.all([ - render(element), - render(element, { plainText: true }), - ]); - await sendAuthEmail(context, { - to: email, - subject: 'Confirm your Treeseed Market email', - text, - html, - }); -} diff --git a/src/lib/auth/email.ts b/src/lib/auth/email.ts deleted file mode 100644 index 4045f282..00000000 --- a/src/lib/auth/email.ts +++ /dev/null @@ -1,365 +0,0 @@ -import type { APIContext } from 'astro'; -import { getSiteAuthConfig } from './config.ts'; - -interface AuthEmailMessage { - to: string; - subject: string; - text: string; - html?: string; -} - -interface SmtpConfig { - host: string; - port: number; - username: string; - password: string; - from: string; - replyTo: string; - secure?: string; -} - -interface StreamSocketContext { - socket?: { - startTls?(): { - readable: ReadableStream; - writable: WritableStream; - }; - }; - reader: ReadableStreamDefaultReader; - writer: WritableStreamDefaultWriter; -} - -function toEnvelopeAddress(value: string) { - const match = value.match(/<([^>]+)>/); - return (match?.[1] ?? value).trim(); -} - -function normalizeBody(text: string) { - return text - .replace(/\r?\n/g, '\r\n') - .split('\r\n') - .map((line) => (line.startsWith('.') ? `.${line}` : line)) - .join('\r\n'); -} - -function buildMessage(message: AuthEmailMessage, smtp: SmtpConfig) { - const boundary = `treeseed-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`; - const headers = [ - `From: ${smtp.from}`, - `To: ${message.to}`, - `Subject: ${message.subject}`, - 'MIME-Version: 1.0', - message.html - ? `Content-Type: multipart/alternative; boundary="${boundary}"` - : 'Content-Type: text/plain; charset=UTF-8', - `Date: ${new Date().toUTCString()}`, - ]; - - if (smtp.replyTo) { - headers.push(`Reply-To: ${smtp.replyTo}`); - } - - if (!message.html) { - return `${headers.join('\r\n')}\r\n\r\n${normalizeBody(message.text)}\r\n.`; - } - - const parts = [ - `--${boundary}`, - 'Content-Type: text/plain; charset=UTF-8', - 'Content-Transfer-Encoding: 8bit', - '', - normalizeBody(message.text), - `--${boundary}`, - 'Content-Type: text/html; charset=UTF-8', - 'Content-Transfer-Encoding: 8bit', - '', - normalizeBody(message.html), - `--${boundary}--`, - ]; - - return `${headers.join('\r\n')}\r\n\r\n${parts.join('\r\n')}\r\n.`; -} - -function assertSmtpConfigured(smtp: SmtpConfig) { - if (!smtp.host || !smtp.port || !smtp.from || !toEnvelopeAddress(smtp.from)) { - throw new Error('SMTP is not fully configured for auth email delivery.'); - } -} - -function assertSmtpResponse(response: { code: number; raw: string }, acceptedCodes: number[]) { - if (!acceptedCodes.includes(response.code)) { - throw new Error(`SMTP command failed: ${response.raw}`); - } -} - -function base64(value: string) { - return btoa(value); -} - -function authPlainPayload(username: string, password: string) { - return base64(`\0${username}\0${password}`); -} - -async function readStreamSmtpResponse(reader: ReadableStreamDefaultReader) { - const decoder = new TextDecoder(); - let buffer = ''; - - while (true) { - const { value, done } = await reader.read(); - if (done) break; - buffer += decoder.decode(value, { stream: true }); - const lines = buffer.split('\r\n').filter(Boolean); - const lastLine = lines.at(-1); - if (lastLine && /^\d{3} /.test(lastLine)) { - return { - code: Number.parseInt(lastLine.slice(0, 3), 10), - raw: buffer, - }; - } - } - - throw new Error('SMTP connection closed unexpectedly.'); -} - -async function sendStreamCommand(context: StreamSocketContext, command: string) { - await context.writer.write(new TextEncoder().encode(`${command}\r\n`)); - return readStreamSmtpResponse(context.reader); -} - -async function authenticateStreamSmtp(context: StreamSocketContext, smtp: SmtpConfig) { - const plain = await sendStreamCommand(context, `AUTH PLAIN ${authPlainPayload(smtp.username, smtp.password)}`); - if (plain.code === 235) return; - if (![500, 502, 504].includes(plain.code)) { - assertSmtpResponse(plain, [235]); - } - assertSmtpResponse(await sendStreamCommand(context, 'AUTH LOGIN'), [334]); - assertSmtpResponse(await sendStreamCommand(context, base64(smtp.username)), [334]); - assertSmtpResponse(await sendStreamCommand(context, base64(smtp.password)), [235]); -} - -async function sendWithCloudflareSockets(message: AuthEmailMessage, smtp: SmtpConfig, siteUrl: string) { - const { connect } = await import('cloudflare:sockets'); - const secureMode = String(smtp.secure ?? '').toLowerCase(); - const secureTransport = ['true', '1', 'tls', 'ssl', 'on'].includes(secureMode) - ? 'on' - : ['starttls', 'required'].includes(secureMode) - ? 'starttls' - : ['false', '0', 'plain', 'off'].includes(secureMode) - ? 'off' - : smtp.port === 465 ? 'on' : smtp.port === 587 ? 'starttls' : 'off'; - let socket = connect( - { hostname: smtp.host, port: smtp.port }, - { secureTransport }, - ); - let context: StreamSocketContext = { - socket, - reader: socket.readable.getReader(), - writer: socket.writable.getWriter(), - }; - const hostname = new URL(siteUrl).hostname || 'localhost'; - - assertSmtpResponse(await readStreamSmtpResponse(context.reader), [220]); - assertSmtpResponse(await sendStreamCommand(context, `EHLO ${hostname}`), [250]); - - if (secureTransport === 'starttls') { - assertSmtpResponse(await sendStreamCommand(context, 'STARTTLS'), [220]); - if (!context.socket?.startTls) { - throw new Error('SMTP socket does not support STARTTLS.'); - } - context.reader.releaseLock(); - context.writer.releaseLock(); - socket = context.socket.startTls(); - context = { - socket, - reader: socket.readable.getReader(), - writer: socket.writable.getWriter(), - }; - assertSmtpResponse(await sendStreamCommand(context, `EHLO ${hostname}`), [250]); - } - - if (smtp.username) { - await authenticateStreamSmtp(context, smtp); - } - - assertSmtpResponse(await sendStreamCommand(context, `MAIL FROM:<${toEnvelopeAddress(smtp.from)}>`), [250]); - assertSmtpResponse(await sendStreamCommand(context, `RCPT TO:<${message.to}>`), [250, 251]); - assertSmtpResponse(await sendStreamCommand(context, 'DATA'), [354]); - assertSmtpResponse(await sendStreamCommand(context, buildMessage(message, smtp)), [250]); - await sendStreamCommand(context, 'QUIT').catch(() => null); - await context.writer.close().catch(() => null); -} - -async function sendWithNodeSockets(message: AuthEmailMessage, smtp: SmtpConfig, siteUrl: string) { - const netSpecifier = 'node:net'; - const tlsSpecifier = 'node:tls'; - const net = await import(/* @vite-ignore */ netSpecifier) as typeof import('node:net'); - const tls = await import(/* @vite-ignore */ tlsSpecifier) as typeof import('node:tls'); - const secureMode = String(smtp.secure ?? '').toLowerCase(); - const secureTransport = ['true', '1', 'tls', 'ssl', 'on'].includes(secureMode) - ? 'on' - : ['starttls', 'required'].includes(secureMode) - ? 'starttls' - : ['false', '0', 'plain', 'off'].includes(secureMode) - ? 'off' - : smtp.port === 465 ? 'on' : smtp.port === 587 ? 'starttls' : 'off'; - let socket = secureTransport === 'on' - ? tls.connect({ host: smtp.host, port: smtp.port, servername: smtp.host }) - : net.connect({ host: smtp.host, port: smtp.port }); - socket.setEncoding('utf8'); - const pending: Array<(value: { code: number; raw: string }) => void> = []; - const failures: Array<(error: Error) => void> = []; - let buffer = ''; - - function attachSocketListeners() { - socket.on('data', (chunk) => { - buffer += String(chunk); - const lines = buffer.split('\r\n').filter(Boolean); - const lastLine = lines.at(-1); - if (!lastLine || !/^\d{3} /.test(lastLine)) return; - const response = { - code: Number.parseInt(lastLine.slice(0, 3), 10), - raw: buffer, - }; - buffer = ''; - pending.shift()?.(response); - }); - socket.on('error', (error) => { - failures.splice(0).forEach((reject) => reject(error)); - }); - } - attachSocketListeners(); - - function readResponse() { - return new Promise<{ code: number; raw: string }>((resolve, reject) => { - pending.push(resolve); - failures.push(reject); - }); - } - - async function send(command: string) { - socket.write(`${command}\r\n`); - return readResponse(); - } - - async function authenticate() { - const plain = await send(`AUTH PLAIN ${authPlainPayload(smtp.username, smtp.password)}`); - if (plain.code === 235) return; - if (![500, 502, 504].includes(plain.code)) { - assertSmtpResponse(plain, [235]); - } - assertSmtpResponse(await send('AUTH LOGIN'), [334]); - assertSmtpResponse(await send(base64(smtp.username)), [334]); - assertSmtpResponse(await send(base64(smtp.password)), [235]); - } - - const hostname = new URL(siteUrl).hostname || 'localhost'; - assertSmtpResponse(await readResponse(), [220]); - assertSmtpResponse(await send(`EHLO ${hostname}`), [250]); - if (secureTransport === 'starttls') { - assertSmtpResponse(await send('STARTTLS'), [220]); - socket.removeAllListeners('data'); - socket.removeAllListeners('error'); - socket = tls.connect({ socket, servername: smtp.host }); - socket.setEncoding('utf8'); - buffer = ''; - attachSocketListeners(); - assertSmtpResponse(await send(`EHLO ${hostname}`), [250]); - } - if (smtp.username) { - await authenticate(); - } - assertSmtpResponse(await send(`MAIL FROM:<${toEnvelopeAddress(smtp.from)}>`), [250]); - assertSmtpResponse(await send(`RCPT TO:<${message.to}>`), [250, 251]); - assertSmtpResponse(await send('DATA'), [354]); - assertSmtpResponse(await send(buildMessage(message, smtp)), [250]); - await send('QUIT').catch(() => null); - socket.end(); -} - -function logConsoleFallback(message: AuthEmailMessage) { - console.info(`[auth-email] ${message.subject} for ${message.to}\n${message.text}`); -} - -function errorMessage(error: unknown) { - return error instanceof Error ? error.message : String(error); -} - -export function authEmailDeliveryFailureReason(error: unknown) { - const message = errorMessage(error).toLowerCase(); - if (/not fully configured|must be configured/u.test(message)) return 'not_configured'; - if (/auth|535|credentials|password|username/u.test(message)) return 'auth_failed'; - if (/mail from|sender|550|553/u.test(message)) return 'sender_rejected'; - if (/rcpt to|recipient|relay/u.test(message)) return 'recipient_rejected'; - if (/starttls|tls|certificate/u.test(message)) return 'tls_failed'; - if (/timeout|timed out|connect|closed unexpectedly|network|unreachable/u.test(message)) return 'connection_failed'; - return 'smtp_failed'; -} - -export function authEmailDeliveryFailureDetail(error: unknown) { - return errorMessage(error) - .replace(/[\r\n\t]+/gu, ' ') - .replace(/\s+/gu, ' ') - .slice(0, 500); -} - -function isLocalAuthUrl(value: string) { - const hostname = new URL(value).hostname; - return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '0.0.0.0'; -} - -function isLocalSmtpHost(value: string) { - return value === 'localhost' || value === '127.0.0.1' || value === '0.0.0.0'; -} - -export function canDeliverAuthEmail(context: Pick | undefined) { - const config = getSiteAuthConfig(context); - const smtp = config.authEmail; - return Boolean(smtp.host && smtp.port && smtp.from) || isLocalAuthUrl(config.betterAuthBaseUrl); -} - -export function authEmailConfigurationMessage() { - return 'Configure SMTP email before using registration, email verification, or password reset.'; -} - -export async function sendAuthEmail(context: Pick | undefined, message: AuthEmailMessage) { - const config = getSiteAuthConfig(context); - const smtp = config.authEmail; - - if (!smtp.host || !smtp.port || !smtp.from) { - if (!isLocalAuthUrl(config.betterAuthBaseUrl)) { - throw new Error('SMTP must be configured before auth email can be delivered outside local development.'); - } - logConsoleFallback(message); - return; - } - - assertSmtpConfigured(smtp); - - if (isLocalAuthUrl(config.betterAuthBaseUrl) && isLocalSmtpHost(smtp.host)) { - try { - await sendWithNodeSockets(message, smtp, config.siteBaseUrl); - return; - } catch (nodeError) { - console.info(`[auth-email] Local SMTP unavailable (${errorMessage(nodeError)}); using console fallback.`); - logConsoleFallback(message); - return; - } - } - - try { - await sendWithCloudflareSockets(message, smtp, config.siteBaseUrl); - return; - } catch (cloudflareError) { - try { - await sendWithNodeSockets(message, smtp, config.siteBaseUrl); - return; - } catch (nodeError) { - if (isLocalAuthUrl(config.betterAuthBaseUrl)) { - console.info(`[auth-email] SMTP delivery failed (${errorMessage(cloudflareError)}; ${errorMessage(nodeError)}); using console fallback.`); - logConsoleFallback(message); - return; - } - throw new Error(`SMTP delivery failed: ${errorMessage(cloudflareError)}; ${errorMessage(nodeError)}`); - } - } -} diff --git a/src/lib/auth/flow.ts b/src/lib/auth/flow.ts deleted file mode 100644 index e05b0804..00000000 --- a/src/lib/auth/flow.ts +++ /dev/null @@ -1,150 +0,0 @@ -import type { APIContext } from 'astro'; -import { getSiteAuthConfig } from './config.ts'; -import { setPrincipalThemeCookies } from './appearance.ts'; -import { resolveApiBaseUrl, setApiAccessTokenCookie } from '../market/api-client.ts'; - -export const SUPPORTED_AUTH_PROVIDERS = ['github', 'google', 'microsoft', 'apple'] as const; -export type SupportedAuthProvider = (typeof SUPPORTED_AUTH_PROVIDERS)[number]; - -const DEFAULT_AUTH_TTL_SECONDS = 15 * 60; - -export function isSupportedAuthProvider(value: string | null | undefined): value is SupportedAuthProvider { - return Boolean(value && (SUPPORTED_AUTH_PROVIDERS as readonly string[]).includes(value)); -} - -export function normalizeReturnTo(context: Pick) { - const value = context.url.searchParams.get('returnTo') ?? context.url.searchParams.get('next') ?? '/app/'; - return value.startsWith('/') && !value.startsWith('//') ? value : '/app/'; -} - -type RedirectStatus = 300 | 301 | 302 | 303 | 304 | 307 | 308; - -type AuthRequestContext = Pick & Partial>; - -function forwardedHeader(context: Pick, name: string) { - const value = context.request.headers.get(name); - return typeof value === 'string' && value.trim() ? value.trim() : ''; -} - -function forwardedClientIp(context: AuthRequestContext) { - const forwardedFor = forwardedHeader(context, 'x-forwarded-for') - .split(',') - .map((part) => part.trim()) - .find(Boolean); - return ( - forwardedHeader(context, 'cf-connecting-ip') - || forwardedHeader(context, 'true-client-ip') - || forwardedHeader(context, 'x-real-ip') - || forwardedFor - || (typeof context.clientAddress === 'string' && context.clientAddress.trim() ? context.clientAddress.trim() : '') - ); -} - -export function authApiJsonHeaders(context: AuthRequestContext) { - const headers = new Headers({ accept: 'application/json', 'content-type': 'application/json' }); - const userAgent = forwardedHeader(context, 'user-agent'); - const clientIp = forwardedClientIp(context); - if (userAgent) headers.set('user-agent', userAgent); - if (clientIp) { - headers.set('x-treeseed-client-ip', clientIp); - headers.set('x-forwarded-for', clientIp); - } - for (const name of ['cf-connecting-ip', 'true-client-ip', 'x-real-ip']) { - const value = forwardedHeader(context, name); - if (value) headers.set(name, value); - } - return headers; -} - -export function redirectAuthenticatedToApp(context: Pick & { redirect: (path: string, status?: RedirectStatus) => Response }) { - return context.locals.auth?.principal ? context.redirect('/app/', 302) : null; -} - -export function authProviderCapabilities(context: Pick) { - const config = getSiteAuthConfig(context); - const providerConfig = config.providers; - return { - mode: config.authMode, - internal: { - enabled: config.internalAuthEnabled, - signup: config.internalSignup, - signupEnabled: config.internalSignupEnabled, - }, - providers: SUPPORTED_AUTH_PROVIDERS.map((id) => ({ - id, - enabled: config.providersEnabled && Boolean(providerConfig[id].clientId && providerConfig[id].clientSecret), - })), - }; -} - -export function providerSignInPath(context: Pick, provider: SupportedAuthProvider, returnTo = normalizeReturnTo(context)) { - const target = new URL(`/v1/auth/oauth/${provider}/start`, resolveApiBaseUrl(context.locals)); - target.searchParams.set('returnTo', returnTo); - target.searchParams.set('callbackUrl', `${context.url.origin}/auth/callback/${provider}?returnTo=${encodeURIComponent(returnTo)}`); - return target.toString(); -} - -export async function submitMarketEmailAuthFlow( - context: AuthRequestContext & Pick, - path: 'sign-in/email' | 'sign-up/email', - body: Record, - options: { finalize?: boolean } = {}, -) { - const endpoint = path === 'sign-up/email' ? '/v1/auth/web/sign-up' : '/v1/auth/web/sign-in'; - const headers = authApiJsonHeaders(context); - try { - const response = await fetch(`${resolveApiBaseUrl(context.locals)}${endpoint}`, { - method: 'POST', - headers, - body: JSON.stringify(body), - }); - const envelope = await response.json().catch(() => null); - const confirmationRequired = path === 'sign-up/email' && envelope?.payload?.confirmationRequired === true; - if (!response.ok || envelope?.ok === false || (!envelope?.payload?.accessToken && !confirmationRequired)) { - return { - ok: false as const, - status: response.status, - error: envelope?.error ?? 'Authentication failed.', - setCookies: [], - }; - } - if (confirmationRequired) { - return { - ok: true as const, - confirmationRequired: true as const, - setCookies: [], - user: { - id: null, - email: envelope.payload.email ?? body.email ?? null, - username: body.username ?? null, - name: body.name ?? body.email ?? null, - }, - session: null, - }; - } - if (options.finalize !== false) { - setApiAccessTokenCookie(context, envelope.payload.accessToken, Number(envelope.payload.expiresInSeconds ?? DEFAULT_AUTH_TTL_SECONDS)); - setPrincipalThemeCookies(context, envelope.payload.principal); - } - return { - ok: true as const, - confirmationRequired: false as const, - setCookies: [], - user: { - id: envelope.payload.principal?.id, - email: envelope.payload.principal?.metadata?.email ?? body.email ?? null, - username: envelope.payload.principal?.metadata?.username ?? body.username ?? null, - name: envelope.payload.principal?.displayName ?? body.name ?? body.email ?? null, - }, - session: envelope.payload, - }; - } catch (error: any) { - const errorBody = error?.body as { message?: string; code?: string } | undefined; - return { - ok: false as const, - status: typeof error?.statusCode === 'number' ? error.statusCode : 500, - error: errorBody?.message ?? error?.message ?? errorBody?.code ?? 'Authentication failed.', - setCookies: [], - }; - } -} diff --git a/src/lib/auth/password-policy.ts b/src/lib/auth/password-policy.ts deleted file mode 100644 index 720a580e..00000000 --- a/src/lib/auth/password-policy.ts +++ /dev/null @@ -1,71 +0,0 @@ -export interface PasswordRuleResult { - id: string; - label: string; - met: boolean; -} - -export interface PasswordStrengthResult { - score: number; - label: string; - rules: PasswordRuleResult[]; -} - -const PASSWORD_MIN_LENGTH = 12; - -export const PASSWORD_RULE_DEFINITIONS = [ - { - id: 'length', - label: `At least ${PASSWORD_MIN_LENGTH} characters`, - test: (value: string) => value.length >= PASSWORD_MIN_LENGTH, - }, - { - id: 'lowercase', - label: 'One lowercase letter', - test: (value: string) => /[a-z]/.test(value), - }, - { - id: 'uppercase', - label: 'One uppercase letter', - test: (value: string) => /[A-Z]/.test(value), - }, - { - id: 'number', - label: 'One number', - test: (value: string) => /\d/.test(value), - }, - { - id: 'symbol', - label: 'One symbol', - test: (value: string) => /[^A-Za-z0-9\s]/.test(value), - }, - { - id: 'spaces', - label: 'No spaces', - test: (value: string) => value.length > 0 && !/\s/.test(value), - }, -] as const; - -export function evaluatePasswordStrength(password: string): PasswordStrengthResult { - const rules = PASSWORD_RULE_DEFINITIONS.map((rule) => ({ - id: rule.id, - label: rule.label, - met: rule.test(password), - })); - const score = rules.filter((rule) => rule.met).length; - const label = score === rules.length - ? 'Strong' - : score >= 4 - ? 'Almost there' - : score >= 2 - ? 'Weak' - : 'Too weak'; - return { score, label, rules }; -} - -export function passwordMeetsPolicy(password: string) { - return evaluatePasswordStrength(password).rules.every((rule) => rule.met); -} - -export function passwordPolicyMessage() { - return `Password must be at least ${PASSWORD_MIN_LENGTH} characters and include uppercase, lowercase, number, symbol, and no spaces.`; -} diff --git a/src/lib/auth/session-refresh.ts b/src/lib/auth/session-refresh.ts new file mode 100644 index 00000000..8c58bc7a --- /dev/null +++ b/src/lib/auth/session-refresh.ts @@ -0,0 +1,24 @@ +import type { APIContext } from 'astro'; +import { applicationSession, apiResource, setRequestCredential } from './application-session'; + +export async function loadApiBackedWebSession(context: APIContext) { + if (!(context.request.headers.get('cookie') ?? '').split(';').some(value => value.trim().startsWith('__Host-treeseed-admin='))) return null; + const credential = await (await applicationSession(context)).session(context.request); + if (!credential) return null; + const response = await fetch(`${apiResource(context)}/v1/me`, { + headers: { accept: 'application/json', authorization: `Bearer ${credential.accessToken}` }, + credentials: 'omit', redirect: 'error', signal: AbortSignal.timeout(10000), + }); + if (response.status === 401) return null; + if (!response.ok) throw new Error('Account access is unavailable.'); + const envelope = await response.json(); + const payload = envelope?.data; + if (!payload?.principal || payload.principal.id !== credential.principal.principalId) throw new Error('Account identity does not match this session.'); + setRequestCredential(context, credential); + return { + id: 'identity-browser-session', userId: payload.principal.id, + email: payload.email ?? payload.principal.email ?? null, + displayName: payload.displayName ?? payload.principal.displayName ?? null, + expiresAt: new Date(credential.expiresAt).toISOString(), principal: payload.principal, + }; +} diff --git a/src/lib/auth/support/access-policy.ts b/src/lib/auth/support/access-policy.ts new file mode 100644 index 00000000..c2ed78a0 --- /dev/null +++ b/src/lib/auth/support/access-policy.ts @@ -0,0 +1,8 @@ +export function isAnonymousAuthRoute(pathname: string) { + return pathname === '/auth/sign-in'; +} + +export function authenticatedAuthRedirect(pathname: string, hasUsername: boolean) { + if (!isAnonymousAuthRoute(pathname)) return null; + return hasUsername ? '/app/' : '/auth/username'; +} diff --git a/src/lib/auth/support/csrf.ts b/src/lib/auth/support/csrf.ts new file mode 100644 index 00000000..3c1717b6 --- /dev/null +++ b/src/lib/auth/support/csrf.ts @@ -0,0 +1,26 @@ +import type { APIContext } from 'astro'; +import { randomBytes, timingSafeEqual } from 'node:crypto'; +import { WEB_CSRF_COOKIE, csrfCookieOptions } from '../configuration/config'; + +export const WEB_CSRF_HEADER = 'x-treeseed-csrf'; + +export function ensureCsrfToken(context: Pick) { + const existing = context.cookies.get(WEB_CSRF_COOKIE)?.value; + if (existing) return existing; + const token = randomBytes(32).toString('base64url'); + context.cookies.set(WEB_CSRF_COOKIE, token, csrfCookieOptions(context.url, 7 * 24 * 60 * 60)); + return token; +} + +export function csrfMatches(context: Pick, candidate: unknown) { + const expected = context.cookies.get(WEB_CSRF_COOKIE)?.value ?? ''; + const actual = typeof candidate === 'string' ? candidate : ''; + if (!expected || !actual) return false; + const left = Buffer.from(expected); + const right = Buffer.from(actual); + return left.length === right.length && timingSafeEqual(left, right); +} + +export function requireCsrf(context: Pick, candidate: unknown) { + if (!csrfMatches(context, candidate)) throw Object.assign(new Error('The form expired. Refresh the page and try again.'), { status: 403, code: 'csrf' }); +} diff --git a/src/lib/auth/delete-confirmation.ts b/src/lib/auth/support/delete-confirmation.ts similarity index 100% rename from src/lib/auth/delete-confirmation.ts rename to src/lib/auth/support/delete-confirmation.ts diff --git a/src/lib/auth/support/flow.ts b/src/lib/auth/support/flow.ts new file mode 100644 index 00000000..1723655a --- /dev/null +++ b/src/lib/auth/support/flow.ts @@ -0,0 +1,11 @@ +import type { APIContext } from 'astro'; + +export function normalizeReturnTo(context: Pick) { + const value = context.url.searchParams.get('returnTo') ?? context.url.searchParams.get('next') ?? '/app/'; + const resolved = new URL(value, context.url.origin); + return resolved.origin === context.url.origin ? resolved.pathname + resolved.search : '/app/'; +} + +export function redirectAuthenticatedToApp(context: Pick & { redirect: (path: string, status?: 302) => Response }) { + return context.locals.auth?.principal ? context.redirect('/app/', 302) : null; +} diff --git a/src/lib/auth/profile-validation.ts b/src/lib/auth/support/profile-validation.ts similarity index 100% rename from src/lib/auth/profile-validation.ts rename to src/lib/auth/support/profile-validation.ts diff --git a/src/lib/auth/support/rbac.ts b/src/lib/auth/support/rbac.ts new file mode 100644 index 00000000..1bf2afe8 --- /dev/null +++ b/src/lib/auth/support/rbac.ts @@ -0,0 +1,17 @@ +export interface PermissionPrincipal { + roles?: readonly string[] | null; + permissions?: readonly string[] | null; +} + +/** Presentation-only permission check over API-issued principal claims. */ +export function principalHasPlatformPermission( + principal: PermissionPrincipal | null | undefined, + permission: string, +) { + return Boolean( + principal + && (principal.roles?.includes('platform_admin') + || principal.permissions?.includes('*:*:*') + || principal.permissions?.includes(permission)), + ); +} diff --git a/src/lib/auth/welcome-email.ts b/src/lib/auth/welcome-email.ts deleted file mode 100644 index d5117cf2..00000000 --- a/src/lib/auth/welcome-email.ts +++ /dev/null @@ -1,163 +0,0 @@ -import React from 'react'; -import { render } from '@react-email/render'; -import type { APIContext } from 'astro'; -import { sendAuthEmail } from './email.ts'; -import { getSiteAuthConfig } from './config.ts'; - -interface WelcomeEmailInput { - email: string; - displayName?: string | null; - signInUrl?: string; -} - -const colors = { - page: '#f6f7f2', - ink: '#17211b', - muted: '#526052', - border: '#d9ded4', - card: '#ffffff', - green: '#2f6f4e', - greenDark: '#24573d', - gold: '#d9a441', -}; - -function WelcomeEmail({ displayName, signInUrl }: { displayName: string; signInUrl: string }) { - return React.createElement('html', { lang: 'en' }, - React.createElement('body', { - style: { - margin: 0, - backgroundColor: colors.page, - color: colors.ink, - fontFamily: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif', - }, - }, - React.createElement('div', { style: { padding: '32px 18px' } }, - React.createElement('div', { - style: { - maxWidth: 560, - margin: '0 auto', - backgroundColor: colors.card, - border: `1px solid ${colors.border}`, - borderRadius: 8, - overflow: 'hidden', - boxShadow: '0 18px 40px rgba(19, 31, 22, 0.08)', - }, - }, - React.createElement('div', { - style: { - padding: '28px 32px 22px', - backgroundColor: '#edf2e9', - borderBottom: `1px solid ${colors.border}`, - }, - }, - React.createElement('div', { - style: { - display: 'inline-block', - padding: '5px 9px', - borderRadius: 999, - backgroundColor: '#fff7df', - color: '#6e4c0d', - fontSize: 12, - fontWeight: 700, - letterSpacing: 0, - marginBottom: 16, - }, - }, 'Email verified'), - React.createElement('h1', { - style: { - margin: 0, - fontSize: 28, - lineHeight: '34px', - fontWeight: 800, - letterSpacing: 0, - }, - }, `Welcome to Treeseed Market, ${displayName}.`), - React.createElement('p', { - style: { - margin: '12px 0 0', - color: colors.muted, - fontSize: 15, - lineHeight: '23px', - }, - }, 'Your account is ready. Treeseed Market is where teams launch, connect, and manage working Treeseed projects.')), - React.createElement('div', { style: { padding: '28px 32px 32px' } }, - React.createElement('p', { - style: { - margin: '0 0 18px', - color: colors.muted, - fontSize: 15, - lineHeight: '24px', - }, - }, 'Sign in to create your first team, connect project infrastructure, and start shaping the workspace around the way your collaborators actually work.'), - React.createElement('a', { - href: signInUrl, - style: { - display: 'inline-block', - backgroundColor: colors.green, - color: '#ffffff', - textDecoration: 'none', - borderRadius: 6, - padding: '12px 18px', - fontWeight: 800, - fontSize: 14, - }, - }, 'Sign in to Treeseed Market'), - React.createElement('div', { - style: { - marginTop: 24, - paddingTop: 20, - borderTop: `1px solid ${colors.border}`, - }, - }, - React.createElement('p', { - style: { - margin: 0, - color: colors.muted, - fontSize: 13, - lineHeight: '20px', - }, - }, 'If the button does not work, open this link in your browser:'), - React.createElement('p', { - style: { - margin: '6px 0 0', - color: colors.greenDark, - fontSize: 13, - lineHeight: '20px', - wordBreak: 'break-all', - }, - }, signInUrl)), - React.createElement('p', { - style: { - margin: '24px 0 0', - color: colors.muted, - fontSize: 12, - lineHeight: '18px', - }, - }, 'You are receiving this because this email address was verified for a Treeseed Market account.')))))); -} - -function firstName(value: string) { - return value.trim().split(/\s+/u)[0] || value; -} - -export async function sendWelcomeEmail( - context: Pick, - input: WelcomeEmailInput, -) { - const email = input.email.trim(); - if (!email) return; - const config = getSiteAuthConfig(context); - const displayName = firstName(input.displayName?.trim() || email.split('@')[0] || 'there'); - const signInUrl = input.signInUrl ?? `${config.siteBaseUrl.replace(/\/+$/u, '')}/auth/sign-in?verified=1`; - const element = React.createElement(WelcomeEmail, { displayName, signInUrl }); - const [html, text] = await Promise.all([ - render(element), - render(element, { plainText: true }), - ]); - await sendAuthEmail(context, { - to: email, - subject: 'Welcome to Treeseed Market', - text, - html, - }); -} diff --git a/src/lib/forms/page-submission.ts b/src/lib/forms/page-submission.ts new file mode 100644 index 00000000..414b9e84 --- /dev/null +++ b/src/lib/forms/page-submission.ts @@ -0,0 +1,22 @@ +import type { APIContext } from 'astro'; +import { formSubmissionResponse, type FormSubmissionResponse } from '@treeseed/ui/forms'; + +export function pageFormResponse( + context: APIContext, + result: FormSubmissionResponse, + fallbackRedirect: string, +) { + const response = formSubmissionResponse(context.request, result, { fallbackRedirect }); + for (const cookie of context.cookies.headers()) response.headers.append('set-cookie', cookie); + return response; +} + +export function pageFormFailure( + context: APIContext, + message: string, + fallbackRedirect: string, + fieldErrors?: Record, + code = 'form_submission_failed', +) { + return pageFormResponse(context, { ok: false, code, message, fieldErrors }, fallbackRedirect); +} diff --git a/src/lib/help/context.ts b/src/lib/help/context.ts new file mode 100644 index 00000000..1f78839f --- /dev/null +++ b/src/lib/help/context.ts @@ -0,0 +1,64 @@ +import type { HelpContext, KnowledgeHelpLink, KnowledgeHelpPage } from '@treeseed/ui'; +import type { APIContext } from 'astro'; +import { ADMIN_ROUTES } from '../../routes.ts'; + +function routeRegex(pattern: string) { + const source = pattern.split('/').map((segment) => ( + /^\[[^\]]+\]$/u.test(segment) + ? '[^/]+' + : segment.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&') + )).join('/'); + return new RegExp(`^${source}/?$`, 'u'); +} + +function routeFor(pathname: string) { + for (const route of ADMIN_ROUTES) { + if (!routeRegex(route.pattern).test(pathname)) continue; + const patternSegments = route.pattern.split('/'); + const pathSegments = pathname.replace(/\/+$/u, '').split('/'); + const params = Object.fromEntries(patternSegments.flatMap((segment, index) => { + const match = segment.match(/^\[([^\]]+)\]$/u); + return match && pathSegments[index] ? [[match[1], decodeURIComponent(pathSegments[index])]] : []; + })); + return { route, params }; + } + return null; +} + +export async function loadRouteHelpContext( + astro: APIContext, + pathname: string, + teamId?: string, + options: { shell?: HelpContext['shell']; context?: HelpContext['context'] } = {}, +): Promise { + const matched = routeFor(pathname); + const route = matched?.route; + const capability = route?.capability; + const knowledgePageId = capability?.knowledgePageIds?.[0]; + if (!route || !capability || !knowledgePageId) return undefined; + const scopedTeamId = matched?.params.teamId ?? teamId; + // Help content is runtime-owned and intentionally loaded only when the user + // opens the dialog. Server-rendering an application route must never wait on + // a federated content or graph query. + const page: KnowledgeHelpPage | undefined = undefined; + const relatedDocs: KnowledgeHelpLink[] = []; + return { + capabilityId: capability.id, + knowledgePageIds: [knowledgePageId], + shell: options.shell ?? 'product', + context: options.context ?? (capability.surface === 'personal' ? 'personal' : 'team'), + resourceType: capability.resourceType, + routePattern: route.pattern, + canonicalPath: pathname, + summary: `Open guidance for ${capability.description}`, + knowledgePages: page ? [page] : [], + relatedDocs, + relatedActions: [], + searchScope: 'global', + visibility: 'authenticated', + pageEndpoint: '/v1/knowledge/pages/{pageId}', + searchEndpoint: '/v1/knowledge/search', + teamId: scopedTeamId, + locale: 'en', + }; +} diff --git a/src/lib/host-crypto.ts b/src/lib/host-crypto.ts deleted file mode 100644 index 1e795bcc..00000000 --- a/src/lib/host-crypto.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { - buildTreeseedClientEncryptedEscrowEnvelope, -} from '@treeseed/sdk/secrets-capability'; - -const TEXT_ENCODER = new TextEncoder(); -const TEXT_DECODER = new TextDecoder(); - -type Sodium = { - ready: Promise; - base64_variants: { ORIGINAL: number }; - crypto_pwhash_ALG_ARGON2ID13: number; - crypto_pwhash_MEMLIMIT_INTERACTIVE: number; - crypto_pwhash_OPSLIMIT_INTERACTIVE: number; - crypto_pwhash_SALTBYTES: number; - crypto_secretbox_KEYBYTES: number; - crypto_secretbox_NONCEBYTES: number; - crypto_pwhash: (keyLength: number, passphrase: Uint8Array, salt: Uint8Array, opsLimit: number, memLimit: number, algorithm: number) => Uint8Array; - crypto_secretbox_easy: (message: Uint8Array, nonce: Uint8Array, key: Uint8Array) => Uint8Array; - crypto_secretbox_open_easy: (ciphertext: Uint8Array, nonce: Uint8Array, key: Uint8Array) => Uint8Array | false; - from_base64: (value: string, variant: number) => Uint8Array; - randombytes_buf: (length: number) => Uint8Array; - to_base64: (bytes: Uint8Array, variant: number) => string; -}; - -export type HostEncryptedPayload = { - version: 1; - algorithm: 'secretbox'; - kdf: { - algorithm: 'argon2id'; - opsLimit: number; - memLimit: number; - }; - salt: string; - nonce: string; - ciphertext: string; -}; - -type TestHostEncryptedPayload = { - algorithm: 'test-json'; - ciphertext: string; - passphrase?: string; - testPassphrase?: string; -}; - -export type HostCredentialConfig = Record; -type TreeseedClientEncryptedEscrowEnvelopeInput = Parameters[0]; - -export type HostCryptoOptions = { - opsLimit?: number; - memLimit?: number; -}; - -export type HostEscrowEnvelopeOptions = { - id: string; - secretId: string; - ciphertextRef: string; - wrappingKeyId: string; - teamId?: string | null; - projectId?: string | null; - createdByClientId?: string | null; - expiresAt?: string | null; - deploymentIntent?: TreeseedClientEncryptedEscrowEnvelopeInput['deploymentIntent']; - metadata?: Record; -}; - -async function loadSodium(): Promise { - let imported: unknown; - try { - imported = await import('libsodium-wrappers-sumo'); - } catch (error) { - if (typeof process === 'undefined' || !process.versions?.node) throw error; - const nodeModuleSpecifier = 'node:module'; - const { createRequire } = await import(/* @vite-ignore */ nodeModuleSpecifier); - const require = createRequire(import.meta.url); - imported = require('libsodium-wrappers-sumo'); - } - const sodium = ((imported as { default?: Sodium }).default ?? imported) as Sodium; - await sodium.ready; - if (typeof sodium.randombytes_buf !== 'function') { - throw new Error('Host encryption could not load browser crypto support.'); - } - return sodium; -} - -function toBase64(sodium: Sodium, bytes: Uint8Array): string { - return sodium.to_base64(bytes, sodium.base64_variants.ORIGINAL); -} - -function fromBase64(sodium: Sodium, value: string): Uint8Array { - return sodium.from_base64(value, sodium.base64_variants.ORIGINAL); -} - -function deriveKey(sodium: Sodium, passphrase: string, salt: Uint8Array, opsLimit: number, memLimit: number): Uint8Array { - return sodium.crypto_pwhash( - sodium.crypto_secretbox_KEYBYTES, - TEXT_ENCODER.encode(passphrase.normalize('NFKC')), - salt, - opsLimit, - memLimit, - sodium.crypto_pwhash_ALG_ARGON2ID13, - ); -} - -export async function encryptHostConfig(config: HostCredentialConfig, passphrase: string, options: HostCryptoOptions = {}): Promise { - if (!passphrase || typeof passphrase !== 'string') { - throw new Error('A passphrase is required to encrypt a host.'); - } - const sodium = await loadSodium(); - const opsLimit = Number(options.opsLimit ?? sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE); - const memLimit = Number(options.memLimit ?? sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE); - const salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES); - const nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES); - const key = deriveKey(sodium, passphrase, salt, opsLimit, memLimit); - const message = TEXT_ENCODER.encode(JSON.stringify(config ?? {})); - const ciphertext = sodium.crypto_secretbox_easy(message, nonce, key); - return { - version: 1, - algorithm: 'secretbox', - kdf: { - algorithm: 'argon2id', - opsLimit, - memLimit, - }, - salt: toBase64(sodium, salt), - nonce: toBase64(sodium, nonce), - ciphertext: toBase64(sodium, ciphertext), - }; -} - -export async function decryptHostConfig(envelope: HostEncryptedPayload | TestHostEncryptedPayload | null | undefined, passphrase: string): Promise { - if (!passphrase || typeof passphrase !== 'string') { - throw new Error('A passphrase is required to decrypt a host.'); - } - if (!envelope || typeof envelope !== 'object') { - throw new Error('A valid encrypted host envelope is required.'); - } - if ( - envelope.algorithm === 'test-json' - && (typeof process !== 'undefined') - && (process.env.NODE_ENV === 'test' || process.env.TREESEED_LOCAL_DEV_MODE) - ) { - const expected = envelope.passphrase ?? envelope.testPassphrase ?? passphrase; - if (expected !== passphrase) { - throw new Error('Unable to decrypt host config. Check the passphrase.'); - } - return JSON.parse(TEXT_DECODER.decode(Uint8Array.from(atob(envelope.ciphertext), (char) => char.charCodeAt(0)))) as HostCredentialConfig; - } - const sodium = await loadSodium(); - const secretboxEnvelope = envelope as HostEncryptedPayload; - const salt = fromBase64(sodium, secretboxEnvelope.salt); - const nonce = fromBase64(sodium, secretboxEnvelope.nonce); - const ciphertext = fromBase64(sodium, secretboxEnvelope.ciphertext); - const key = deriveKey( - sodium, - passphrase, - salt, - Number(secretboxEnvelope.kdf?.opsLimit ?? sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE), - Number(secretboxEnvelope.kdf?.memLimit ?? sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE), - ); - const plaintext = sodium.crypto_secretbox_open_easy(ciphertext, nonce, key); - if (!plaintext) { - throw new Error('Unable to decrypt host config. Check the passphrase.'); - } - return JSON.parse(TEXT_DECODER.decode(plaintext)) as HostCredentialConfig; -} - -export function hostEncryptedPayloadToClientEscrowEnvelope( - payload: HostEncryptedPayload, - options: HostEscrowEnvelopeOptions, -): TreeseedClientEncryptedEscrowEnvelopeInput { - return buildTreeseedClientEncryptedEscrowEnvelope({ - id: options.id, - secretId: options.secretId, - teamId: options.teamId, - projectId: options.projectId, - ciphertext: payload.ciphertext, - ciphertextRef: options.ciphertextRef, - algorithm: payload.algorithm, - nonce: payload.nonce, - salt: payload.salt, - kdf: payload.kdf.algorithm, - kdfParams: { - opsLimit: payload.kdf.opsLimit, - memLimit: payload.kdf.memLimit, - }, - wrappingKeyId: options.wrappingKeyId, - encryptionVersion: `host-payload-v${payload.version}`, - createdByClientId: options.createdByClientId, - expiresAt: options.expiresAt, - deploymentIntent: options.deploymentIntent ?? { targetMode: 'metadata_only_reentry' }, - metadata: { - source: 'admin_host_credential_form', - ...(options.metadata ?? {}), - }, - status: 'active', - }); -} diff --git a/src/lib/knowledge-distribution/publish-client.ts b/src/lib/knowledge-distribution/publish-client.ts deleted file mode 100644 index df97a665..00000000 --- a/src/lib/knowledge-distribution/publish-client.ts +++ /dev/null @@ -1,23 +0,0 @@ -const allowedProjectActions = new Set(['share/export', 'share/package-template', 'share/package-knowledge-pack', 'share/publish']); - -export async function submitKnowledgeDistributionAction(form: HTMLFormElement, status: HTMLElement | null): Promise { - const data = new FormData(form); - const projectId = String(data.get('projectId') ?? ''); - const action = String(data.get('action') ?? ''); - if (!projectId || !allowedProjectActions.has(action)) { - if (status) status.textContent = 'Choose a project and distribution action.'; - return; - } - if (status) status.textContent = 'Submitting...'; - const response = await fetch(`/v1/projects/${encodeURIComponent(projectId)}/${action}`, { - method: 'POST', - headers: { 'content-type': 'application/json' }, - body: JSON.stringify({ source: 'knowledge-distribution' }), - }); - const payload = await response.json().catch(() => null); - if (!response.ok || payload?.ok === false) { - if (status) status.textContent = payload?.error ?? 'Action failed.'; - return; - } - if (status) status.textContent = 'Submitted.'; -} diff --git a/src/lib/market/admin-form-client.ts b/src/lib/market/admin-form-client.ts deleted file mode 100644 index 76c3e6e8..00000000 --- a/src/lib/market/admin-form-client.ts +++ /dev/null @@ -1,110 +0,0 @@ -type AdminFormContext = { - form: HTMLFormElement; - formData: FormData; - setStatus: (message: string) => void; - submitter: HTMLElement | null; -}; - -type AdminFormOptions = { - statusElement?: HTMLElement | null; - busyMessage?: string; - successMessage?: string; - preserveServerValues?: boolean; - onSubmit: (context: AdminFormContext) => Promise; - onSuccess?: (result: unknown, context: AdminFormContext) => void; -}; - -function formControls(form: HTMLFormElement) { - return [...form.querySelectorAll('input, textarea, select')]; -} - -function resetControlToServerValue(control: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement) { - if (control instanceof HTMLSelectElement) { - for (const option of control.options) option.selected = option.defaultSelected; - return; - } - if (control instanceof HTMLTextAreaElement) { - control.value = control.defaultValue; - return; - } - if (control.type === 'checkbox' || control.type === 'radio') { - control.checked = control.defaultChecked; - return; - } - if (control.type === 'hidden' || control.dataset.allowBrowserAutofill === 'true') return; - control.value = control.defaultValue; -} - -export function protectAdministrativeFormValues(form: HTMLFormElement) { - let userInteracted = false; - const markInteracted = () => { - userInteracted = true; - }; - form.addEventListener('focusin', markInteracted, { once: true }); - form.addEventListener('input', markInteracted, { once: true }); - form.setAttribute('autocomplete', 'off'); - for (const control of formControls(form)) { - if (control instanceof HTMLInputElement || control instanceof HTMLTextAreaElement) { - control.setAttribute('autocomplete', control.getAttribute('autocomplete') || 'off'); - control.setAttribute('autocapitalize', control.getAttribute('autocapitalize') || 'none'); - control.setAttribute('spellcheck', control.getAttribute('spellcheck') || 'false'); - control.setAttribute('data-lpignore', control.getAttribute('data-lpignore') || 'true'); - control.setAttribute('data-1p-ignore', control.getAttribute('data-1p-ignore') || 'true'); - } - } - const resetIfBrowserFilled = () => { - if (userInteracted) return; - for (const control of formControls(form)) resetControlToServerValue(control); - }; - resetIfBrowserFilled(); - window.setTimeout(resetIfBrowserFilled, 100); - window.setTimeout(resetIfBrowserFilled, 500); -} - -export async function submitAdministrativeJson(url: string, method: string, body?: unknown) { - const response = await fetch(url, { - method, - headers: body === undefined ? undefined : { 'content-type': 'application/json' }, - body: body === undefined ? undefined : JSON.stringify(body), - }); - const payload = await response.json().catch(() => null); - if (!response.ok || payload?.ok === false) { - throw new Error(payload?.error ?? `Request failed with ${response.status}.`); - } - return payload?.payload ?? payload; -} - -export function bindAdministrativeForm(form: HTMLFormElement | null, options: AdminFormOptions) { - if (!form || form.dataset.adminFormBound === 'true') return; - form.dataset.adminFormBound = 'true'; - if (options.preserveServerValues) protectAdministrativeFormValues(form); - const status = options.statusElement ?? null; - const setStatus = (message: string) => { - if (status) status.textContent = message; - }; - const submitButtons = () => [...form.querySelectorAll('button[type="submit"], input[type="submit"]')]; - form.addEventListener('invalid', (event) => { - const target = event.target as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null; - setStatus(target?.name ? `Check "${target.name}" before saving.` : 'Check the highlighted fields before saving.'); - }, true); - form.addEventListener('submit', async (event) => { - event.preventDefault(); - if (!form.reportValidity()) { - setStatus('Check the highlighted fields before saving.'); - return; - } - const submitter = event.submitter instanceof HTMLElement ? event.submitter : null; - for (const button of submitButtons()) button.disabled = true; - setStatus(options.busyMessage ?? 'Saving...'); - const context: AdminFormContext = { form, formData: new FormData(form), setStatus, submitter }; - try { - const result = await options.onSubmit(context); - options.onSuccess?.(result, context); - if (!options.onSuccess) setStatus(options.successMessage ?? 'Saved.'); - } catch (error) { - setStatus(error instanceof Error ? error.message : 'Form could not be saved.'); - } finally { - for (const button of submitButtons()) button.disabled = false; - } - }); -} diff --git a/src/lib/market/api-client.ts b/src/lib/market/api-client.ts index 3a9d6156..53b20106 100644 --- a/src/lib/market/api-client.ts +++ b/src/lib/market/api-client.ts @@ -1,965 +1,93 @@ import type { APIContext } from 'astro'; -import { TREESEED_REMOTE_CONTRACT_HEADER, TREESEED_REMOTE_CONTRACT_VERSION } from '@treeseed/sdk/remote'; -import { getSiteAuthConfig } from '../auth/config'; - -type AstroLike = Pick; - -const API_SESSION_COOKIE = 'ts_market_api_access'; - -function getNodeCrypto(): - | { - createHmac?: (algorithm: string, secret: string) => { update: (value: string) => { digest: (encoding: 'base64url') => string } }; - randomUUID?: () => string; - timingSafeEqual?: (left: Uint8Array, right: Uint8Array) => boolean; - } - | null { - return (globalThis as { process?: { getBuiltinModule?: (name: string) => unknown } }).process - ?.getBuiltinModule?.('crypto') as ReturnType ?? null; +import { REMOTE_CONTRACT_HEADER, REMOTE_CONTRACT_VERSION } from '@treeseed/sdk/site-contracts/catalog'; +import { identityEndpointSchema } from '@treeseed/sdk/identity'; +import type { AccountDeletionBlocker, AccountEmailAddress, AccountEmailMutationResult, AccountIdentity, AccountMutationResult, AccountNotification, AccountWebSession, AuthProviderCapability, NotificationPreferences, NotificationProject, PersonalTheme, PersonalThemeDraft, UsernameClaimResult, WebAuthenticationResult } from '@treeseed/sdk/account-contracts'; +export type AstroLike = Pick; +export function getNodeCrypto(): { + createHmac?: (algorithm: string, secret: string) => { + update: (value: string) => { + digest: (encoding: 'base64url') => string; + }; + }; + randomUUID?: () => string; + timingSafeEqual?: (left: Uint8Array, right: Uint8Array) => boolean; +} | null { + return (globalThis as { + process?: { + getBuiltinModule?: (name: string) => unknown; + }; + }).process + ?.getBuiltinModule?.('crypto') as ReturnType ?? null; +} +export function randomId() { + const nodeCrypto = getNodeCrypto(); + if (nodeCrypto?.randomUUID) + return nodeCrypto.randomUUID(); + if (globalThis.crypto?.randomUUID) + return globalThis.crypto.randomUUID(); + const bytes = new Uint8Array(16); + globalThis.crypto?.getRandomValues?.(bytes); + bytes[6] = (bytes[6] & 0x0f) | 0x40; + bytes[8] = (bytes[8] & 0x3f) | 0x80; + const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, '0')).join(''); + return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`; +} +export function runtimeEnv(locals: App.Locals | Record | null | undefined) { + return (locals as App.Locals | undefined)?.runtime?.env as Record | undefined; +} +export function envValue(locals: App.Locals | Record | null | undefined, name: string) { + const runtimeValue = runtimeEnv(locals)?.[name]; + if (typeof runtimeValue === 'string' && runtimeValue.trim()) + return runtimeValue.trim(); + const processValue = (globalThis as { + process?: { + env?: Record; + }; + }).process?.env?.[name]; + return typeof processValue === 'string' && processValue.trim() ? processValue.trim() : ''; } - -function randomId() { - const nodeCrypto = getNodeCrypto(); - if (nodeCrypto?.randomUUID) return nodeCrypto.randomUUID(); - if (globalThis.crypto?.randomUUID) return globalThis.crypto.randomUUID(); - const bytes = new Uint8Array(16); - globalThis.crypto?.getRandomValues?.(bytes); - bytes[6] = (bytes[6] & 0x0f) | 0x40; - bytes[8] = (bytes[8] & 0x3f) | 0x80; - const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, '0')).join(''); - return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`; -} - -function runtimeEnv(locals: App.Locals | Record | null | undefined) { - return (locals as App.Locals | undefined)?.runtime?.env as Record | undefined; -} - -function envValue(locals: App.Locals | Record | null | undefined, name: string) { - const runtimeValue = runtimeEnv(locals)?.[name]; - if (typeof runtimeValue === 'string' && runtimeValue.trim()) return runtimeValue.trim(); - const processValue = (globalThis as { process?: { env?: Record } }).process?.env?.[name]; - return typeof processValue === 'string' && processValue.trim() ? processValue.trim() : ''; -} - export function resolveApiBaseUrl(locals?: App.Locals | Record | null) { - return ( - envValue(locals, 'TREESEED_MARKET_API_BASE_URL') - || envValue(locals, 'TREESEED_CENTRAL_MARKET_API_BASE_URL') - || 'https://api.treeseed.ai' - ).replace(/\/+$/u, ''); -} - -function encodeAssertionPayload(payload: Record) { - return Buffer.from(JSON.stringify(payload)).toString('base64url'); -} - -function signAssertionPayload(payload: string, secret: string) { - const nodeCrypto = getNodeCrypto(); - if (!nodeCrypto?.createHmac) { - throw new Error('Trusted web user assertions require an HMAC-capable runtime.'); - } - return nodeCrypto.createHmac('sha256', secret).update(payload).digest('base64url'); -} - -export function createTrustedWebUserAssertion(context: Pick) { - const principal = context.locals.auth?.principal; - if (!principal?.id) return null; - const config = getSiteAuthConfig(context); - const session = context.locals.auth?.session; - const payload = encodeAssertionPayload({ - userId: principal.id, - sessionId: session?.id ?? principal.metadata?.sessionId ?? null, - identityId: session?.identityId ?? principal.metadata?.identityId ?? null, - authTime: session?.authenticatedAt ?? principal.metadata?.authTime ?? new Date().toISOString(), - expiresAt: new Date(Date.now() + 5 * 60 * 1000).toISOString(), - nonce: randomId(), - }); - return `${payload}.${signAssertionPayload(payload, config.apiAssertionSecret)}`; -} - -export function apiServiceHeaders( - context: Pick, - options: { forceService?: boolean; skipUserAssertion?: boolean } = {}, -) { - const config = getSiteAuthConfig(context); - const headers = new Headers({ - accept: 'application/json', - [TREESEED_REMOTE_CONTRACT_HEADER]: String(TREESEED_REMOTE_CONTRACT_VERSION), - }); - const assertion = options.skipUserAssertion ? null : createTrustedWebUserAssertion(context); - if (assertion || options.forceService) { - headers.set('x-treeseed-service-id', config.apiServiceId); - headers.set('x-treeseed-service-secret', config.apiServiceSecret); - } - if (assertion) headers.set('x-treeseed-user-assertion', assertion); - return headers; -} - -export function apiAccessTokenFromCookies(context: Pick) { - return context.cookies.get(API_SESSION_COOKIE)?.value ?? null; -} - -export function setApiAccessTokenCookie(context: Pick, token: string, maxAgeSeconds: number) { - context.cookies.set(API_SESSION_COOKIE, token, { - httpOnly: true, - path: '/', - sameSite: 'lax', - secure: context.url.protocol === 'https:', - maxAge: maxAgeSeconds, - }); -} - -export function clearApiAccessTokenCookie(context: Pick) { - context.cookies.delete(API_SESSION_COOKIE, { - path: '/', - secure: context.url.protocol === 'https:', - }); -} - -function isObject(value: unknown): value is Record { - return Boolean(value && typeof value === 'object' && !Array.isArray(value)); -} - -function unwrapEnvelope(envelope: any): T { - if (Object.prototype.hasOwnProperty.call(envelope, 'payload')) return envelope.payload as T; - if (Object.prototype.hasOwnProperty.call(envelope, 'provider')) return envelope.provider as T; - if (Object.prototype.hasOwnProperty.call(envelope, 'operations')) return envelope.operations as T; - return envelope as T; -} - + return identityEndpointSchema.parse(envValue(locals, 'TREESEED_API_BASE_URL')).replace(/\/+$/u, ''); +} +export function isObject(value: unknown): value is Record { + return Boolean(value && typeof value === 'object' && !Array.isArray(value)); +} +export function unwrapEnvelope(envelope: any): T { + if (Object.prototype.hasOwnProperty.call(envelope, 'data')) + return envelope.data as T; + if (Object.prototype.hasOwnProperty.call(envelope, 'payload')) + return envelope.payload as T; + if (Object.prototype.hasOwnProperty.call(envelope, 'provider')) + return envelope.provider as T; + if (Object.prototype.hasOwnProperty.call(envelope, 'operations')) + return envelope.operations as T; + return envelope as T; +} +import * as extractedMethods from "./api-client/methods.ts"; +import "./api-client/interface.ts"; +export { catalogOperationPath } from "./api-client/support/contracts/request.ts"; export class ApiClientFacade { - constructor(private readonly context: AstroLike) {} - - private headers(body = false) { - const token = apiAccessTokenFromCookies(this.context); - const headers = apiServiceHeaders(this.context, { skipUserAssertion: Boolean(token) }); - if (token) headers.set('authorization', `Bearer ${token}`); - if (body) headers.set('content-type', 'application/json'); - return headers; - } - - private url(path: string) { - return `${resolveApiBaseUrl(this.context.locals)}${path}`; - } - - async request(method: string, path: string, options: { body?: unknown } = {}): Promise { - const response = await fetch(this.url(path), { - method, - headers: this.headers(options.body !== undefined), - body: options.body === undefined ? undefined : JSON.stringify(options.body), - }); - const envelope = await response.json().catch(() => null); - if (!response.ok || envelope?.ok === false) { - const error = new Error(envelope?.error ?? `API request failed: ${response.status}`); - (error as any).status = response.status; - (error as any).details = isObject(envelope) ? envelope : {}; - throw error; - } - return unwrapEnvelope(envelope); - } - - get currentPrincipal() { - return this.context.locals.auth?.principal ?? null; - } - - listTeamsForPrincipal() { - return this.request('GET', '/v1/teams'); - } - - listTeamProjects(teamId: string) { - return this.request('GET', `/v1/projects?teamId=${encodeURIComponent(teamId)}`); - } - - getProjectDetails(projectId: string) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}`); - } - - validatePrivateKnowledgeAccess(projectId: string, body: { slug?: string; route?: string } = {}) { - return this.request('POST', `/v1/projects/${encodeURIComponent(projectId)}/private-knowledge/access`, { body }); - } - - recordPrivateKnowledgeOutcome(projectId: string, body: { slug?: string; route?: string; outcome: 'read' | 'not_found' }) { - return this.request('POST', `/v1/projects/${encodeURIComponent(projectId)}/private-knowledge/access`, { body }); - } - - getProjectDeployment(deploymentId: string, options: { limit?: number | string | null } = {}) { - const query = new URLSearchParams(); - if (options.limit != null) query.set('limit', String(options.limit)); - return this.request('GET', `/v1/project-deployments/${encodeURIComponent(deploymentId)}${query.toString() ? `?${query}` : ''}`); - } - - listProjectDeployments(projectId: string, filters: { environment?: string; action?: string; status?: string; limit?: number | string } = {}) { - const query = new URLSearchParams(); - if (filters.environment) query.set('environment', filters.environment); - if (filters.action) query.set('action', filters.action); - if (filters.status) query.set('status', filters.status); - if (filters.limit != null) query.set('limit', String(filters.limit)); - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/deployments${query.toString() ? `?${query}` : ''}`); - } - - async listProjectDeploymentEvents(deploymentId: string, options: { limit?: number | string | null } = {}) { - const details = await this.getProjectDeployment(deploymentId, options); - return Array.isArray(details?.events) ? details.events : []; - } - - getProjectByTeamAndSlug(teamId: string, slug: string) { - return this.listTeamProjects(teamId).then((projects) => projects.find((project: any) => project.slug === slug || project.id === slug) ?? null); - } - - getProjectSummary(projectId: string) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/summary`); - } - - getProjectAgentsSummary(projectId: string) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/agents`); - } - - getProjectReleasesSummary(projectId: string) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/releases`); - } - - getProjectCapacitySummary(projectId: string, environment = 'staging') { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/capacity?environment=${encodeURIComponent(environment)}`); - } - - getProjectCapacityOperations(projectId: string, environment = 'staging') { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/capacity/operations?environment=${encodeURIComponent(environment)}`); - } - - listProjectWorkdaySummaries(projectId: string, environment: string | null = null) { - const query = environment ? `?environment=${encodeURIComponent(environment)}` : ''; - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/workdays${query}`); - } - - listRuntimeWorkDays(projectId: string, options: { limit?: number } = {}) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/runtime/workdays?limit=${encodeURIComponent(String(options.limit ?? 100))}`); - } - - listRuntimeTasks(projectId: string, options: { workDayId?: string; limit?: number } = {}) { - const query = new URLSearchParams(); - if (options.workDayId) query.set('workDayId', options.workDayId); - query.set('limit', String(options.limit ?? 100)); - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/runtime/tasks?${query}`); - } - - listRuntimeTaskEvents(projectId: string, taskId: string) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/runtime/tasks/${encodeURIComponent(taskId)}/events`); - } - - listRuntimeTaskOutputs(projectId: string, taskId: string) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/runtime/tasks/${encodeURIComponent(taskId)}/outputs`); - } - - listApprovalRequestsForProject(projectId: string, limit = 100) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/approval-requests?limit=${encodeURIComponent(String(limit))}`); - } - - listApprovalRequestsForTeam(teamId: string, options: { kind?: string; limit?: number } = {}) { - const query = new URLSearchParams(); - if (options.kind) query.set('kind', options.kind); - query.set('limit', String(options.limit ?? 100)); - return this.request('GET', `/v1/teams/${encodeURIComponent(teamId)}/approval-requests?${query}`); - } - - decideApprovalRequest(approvalRequestId: string, body: Record) { - return this.request('POST', `/v1/approval-requests/${encodeURIComponent(approvalRequestId)}/decide`, { body }); - } - - getCommonsSummary() { - return this.request('GET', '/v1/commons/summary'); - } - - getCommonsParticipantMe() { - return this.request('GET', '/v1/commons/participants/me'); - } - - listCommonsParticipants(filters: Record = {}) { - const query = new URLSearchParams(); - for (const [key, value] of Object.entries(filters)) { - if (value != null && value !== '') query.set(key, String(value)); - } - const suffix = query.toString() ? `?${query}` : ''; - return this.request('GET', `/v1/commons/participants${suffix}`); - } - - backfillCommonsParticipants() { - return this.request('POST', '/v1/commons/participants/backfill', { body: {} }); - } - - listCommonsQuestions(filters: Record = {}) { - const query = new URLSearchParams(); - for (const [key, value] of Object.entries(filters)) { - if (value != null && value !== '') query.set(key, String(value)); - } - const suffix = query.toString() ? `?${query}` : ''; - return this.request('GET', `/v1/commons/questions${suffix}`); - } - - answerCommonsQuestion(questionId: string, body: Record) { - return this.request('POST', `/v1/commons/questions/${encodeURIComponent(questionId)}/answer`, { body }); - } - - createCommonsProposal(body: Record) { - return this.request('POST', '/v1/commons/proposals', { body }); - } - - listCommonsProposals(filters: Record = {}) { - const query = new URLSearchParams(); - for (const [key, value] of Object.entries(filters)) { - if (value != null && value !== '') query.set(key, String(value)); - } - const suffix = query.toString() ? `?${query}` : ''; - return this.request('GET', `/v1/commons/proposals${suffix}`); - } - - getCommonsProposal(proposalId: string) { - return this.request('GET', `/v1/commons/proposals/${encodeURIComponent(proposalId)}`); - } - - reviewCommonsProposal(proposalId: string, body: Record = {}) { - return this.request('POST', `/v1/commons/proposals/${encodeURIComponent(proposalId)}/review`, { body }); - } - - startCommonsProposalVoting(proposalId: string, body: Record = {}) { - return this.request('POST', `/v1/commons/proposals/${encodeURIComponent(proposalId)}/start-voting`, { body }); - } - - stewardDecisionForCommonsProposal(proposalId: string, body: Record) { - return this.request('POST', `/v1/commons/proposals/${encodeURIComponent(proposalId)}/steward-decision`, { body }); - } - - listCommonsDecisions(filters: Record = {}) { - const query = new URLSearchParams(); - for (const [key, value] of Object.entries(filters)) { - if (value != null && value !== '') query.set(key, String(value)); - } - const suffix = query.toString() ? `?${query}` : ''; - return this.request('GET', `/v1/commons/decisions${suffix}`); - } - - listCommonsEvents(filters: Record = {}) { - const query = new URLSearchParams(); - for (const [key, value] of Object.entries(filters)) { - if (value != null && value !== '') query.set(key, String(value)); - } - const suffix = query.toString() ? `?${query}` : ''; - return this.request('GET', `/v1/commons/events${suffix}`); - } - - deleteTeamInboxItemsByItemKey(_teamId: string, _itemKey: string) { - return Promise.resolve({ ok: true }); - } - - listPersistedTeamInboxItems(teamId: string) { - return this.request('GET', `/v1/teams/${encodeURIComponent(teamId)}/inbox`); - } - - listAuditEventsForTarget(targetType: string, targetId: string, limit = 100) { - return this.request('GET', `/v1/audit-events?targetType=${encodeURIComponent(targetType)}&targetId=${encodeURIComponent(targetId)}&limit=${encodeURIComponent(String(limit))}`); - } - - listTeamMembers(teamId: string) { - return this.request('GET', `/v1/teams/${encodeURIComponent(teamId)}/members`); - } - - getTeamAccessSummary(teamId: string) { - return this.request('GET', `/v1/teams/${encodeURIComponent(teamId)}/permissions`); - } - - getTeamPortfolioAllocation(teamId: string) { - return this.request('GET', `/v1/teams/${encodeURIComponent(teamId)}/capacity-allocation`); - } - - updateTeamPortfolioAllocation(teamId: string, body: Record) { - return this.request('PUT', `/v1/teams/${encodeURIComponent(teamId)}/capacity-allocation`, { body }); - } - - getProjectAgentClassAllocation(projectId: string) { - return this.request('GET', `/v1/projects/${encodeURIComponent(projectId)}/capacity-allocation`); - } - - updateProjectAgentClassAllocation(projectId: string, body: Record) { - return this.request('PUT', `/v1/projects/${encodeURIComponent(projectId)}/capacity-allocation`, { body }); - } - - getCommerceVendor(teamId: string) { - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}`); - } - - requestCommerceVendor(teamId: string, body: Record) { - return this.request('POST', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/request`, { body }); - } - - getCommerceVendorStripeStatus(teamId: string, refresh = false) { - const query = refresh ? '?refresh=1' : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/stripe/status${query}`); - } - - startCommerceVendorStripeOnboarding(teamId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/stripe/onboarding`, { body }); - } - - markCommerceVendorStripeReturn(teamId: string) { - return this.request('POST', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/stripe/return`, { body: {} }); - } - - createCommerceVendorStripeLoginLink(teamId: string) { - return this.request('POST', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/stripe/login-link`, { body: {} }); - } - - listCommerceProducts(filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/products${suffix}`); - } - - getCommerceProduct(productId: string) { - return this.request('GET', `/v1/commerce/products/${encodeURIComponent(productId)}`); - } - - getCommerceOwnershipWorkflow(productId: string) { - return this.request('GET', `/v1/commerce/products/${encodeURIComponent(productId)}/ownership-workflow`); - } - - updateCommerceOwnershipRecord(productId: string, ownershipRecordId: string, body: Record) { - return this.request('PATCH', `/v1/commerce/products/${encodeURIComponent(productId)}/ownership/${encodeURIComponent(ownershipRecordId)}`, { body }); - } - - updateCommerceStewardshipAssignment(productId: string, assignmentId: string, body: Record) { - return this.request('PATCH', `/v1/commerce/products/${encodeURIComponent(productId)}/stewards/${encodeURIComponent(assignmentId)}`, { body }); - } - - endCommerceStewardshipAssignment(productId: string, assignmentId: string, body: Record) { - return this.request('POST', `/v1/commerce/products/${encodeURIComponent(productId)}/stewards/${encodeURIComponent(assignmentId)}/end`, { body }); - } - - updateCommerceContribution(productId: string, contributionId: string, body: Record) { - return this.request('PATCH', `/v1/commerce/products/${encodeURIComponent(productId)}/contributions/${encodeURIComponent(contributionId)}`, { body }); - } - - updateCommerceGovernancePolicy(productId: string, policyId: string, body: Record) { - return this.request('PATCH', `/v1/commerce/products/${encodeURIComponent(productId)}/governance-policy/${encodeURIComponent(policyId)}`, { body }); - } - - submitCommerceOwnershipTransfer(productId: string, transferId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/products/${encodeURIComponent(productId)}/ownership-transfer/${encodeURIComponent(transferId)}/submit`, { body }); - } - - approveCommerceOwnershipTransfer(productId: string, transferId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/products/${encodeURIComponent(productId)}/ownership-transfer/${encodeURIComponent(transferId)}/approve`, { body }); - } - - rejectCommerceOwnershipTransfer(productId: string, transferId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/products/${encodeURIComponent(productId)}/ownership-transfer/${encodeURIComponent(transferId)}/reject`, { body }); - } - - cancelCommerceOwnershipTransfer(productId: string, transferId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/products/${encodeURIComponent(productId)}/ownership-transfer/${encodeURIComponent(transferId)}/cancel`, { body }); - } - - createCommerceSuccessionEvent(productId: string, body: Record) { - return this.request('POST', `/v1/commerce/products/${encodeURIComponent(productId)}/succession-events`, { body }); - } - - listCommerceSuccessionEvents(productId: string) { - return this.request('GET', `/v1/commerce/products/${encodeURIComponent(productId)}/succession-events`); - } - - getCommerceVendorSalesSummary(teamId: string, filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/sales/summary${suffix}`); - } - - getCommerceVendorMonitoring(teamId: string, filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/monitoring${suffix}`); - } - - listCommerceMarketplaceProducts(filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/marketplace${suffix}`); - } - - getCommerceMarketplaceProduct(productId: string) { - return this.request('GET', `/v1/commerce/marketplace/products/${encodeURIComponent(productId)}`); - } - - listCommerceVendorSalesOrders(teamId: string, filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/sales/orders${suffix}`); - } - - listCommerceVendorSalesSubscriptions(teamId: string, filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/sales/subscriptions${suffix}`); - } - - listCommerceVendorSalesEntitlements(teamId: string, filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/sales/entitlements${suffix}`); - } - - listCommerceVendorSalesRefunds(teamId: string, filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/sales/refunds${suffix}`); - } - - listCommerceVendorFulfillmentEvents(teamId: string, filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/vendors/${encodeURIComponent(teamId)}/sales/fulfillment-events${suffix}`); - } - - createCommerceOrderRefund(orderId: string, body: Record) { - return this.request('POST', `/v1/commerce/orders/${encodeURIComponent(orderId)}/refunds`, { body }); - } - - fulfillCommerceOrderItemArtifact(orderItemId: string, body: Record) { - return this.request('POST', `/v1/commerce/order-items/${encodeURIComponent(orderItemId)}/fulfillment/artifact`, { body }); - } - - revokeCommerceEntitlement(entitlementId: string, body: Record) { - return this.request('POST', `/v1/commerce/entitlements/${encodeURIComponent(entitlementId)}/revoke`, { body }); - } - - createCommerceServiceRequest(body: Record) { - return this.request('POST', '/v1/commerce/services/requests', { body }); - } - - listCommerceServiceRequests(filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/services/requests${suffix}`); - } - - getCommerceServiceRequest(requestId: string) { - return this.request('GET', `/v1/commerce/services/requests/${encodeURIComponent(requestId)}`); - } - - startCommerceServiceScoping(requestId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/services/requests/${encodeURIComponent(requestId)}/scoping`, { body }); - } - - updateCommerceServiceRequest(requestId: string, body: Record) { - return this.request('PATCH', `/v1/commerce/services/requests/${encodeURIComponent(requestId)}`, { body }); - } - - cancelCommerceServiceRequest(requestId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/services/requests/${encodeURIComponent(requestId)}/cancel`, { body }); - } - - createCommerceServiceQuote(requestId: string, body: Record) { - return this.request('POST', `/v1/commerce/services/requests/${encodeURIComponent(requestId)}/quotes`, { body }); - } - - listCommerceServiceQuotes(requestId: string) { - return this.request('GET', `/v1/commerce/services/requests/${encodeURIComponent(requestId)}/quotes`); - } - - submitCommerceServiceQuote(quoteId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/services/quotes/${encodeURIComponent(quoteId)}/submit`, { body }); - } - - buyerApproveCommerceServiceQuote(quoteId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/services/quotes/${encodeURIComponent(quoteId)}/buyer-approve`, { body }); - } - - vendorApproveCommerceServiceQuote(quoteId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/services/quotes/${encodeURIComponent(quoteId)}/vendor-approve`, { body }); - } - - rejectCommerceServiceQuote(quoteId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/services/quotes/${encodeURIComponent(quoteId)}/reject`, { body }); - } - - getCommerceServiceContract(contractId: string) { - return this.request('GET', `/v1/commerce/services/contracts/${encodeURIComponent(contractId)}`); - } - - linkCommerceServiceContractWork(contractId: string, body: Record) { - return this.request('POST', `/v1/commerce/services/contracts/${encodeURIComponent(contractId)}/link-work`, { body }); - } - - fulfillCommerceServiceContract(contractId: string, body: Record) { - return this.request('POST', `/v1/commerce/services/contracts/${encodeURIComponent(contractId)}/fulfill`, { body }); - } - - cancelCommerceServiceContract(contractId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/services/contracts/${encodeURIComponent(contractId)}/cancel`, { body }); - } - - listCommerceServiceEvents(filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/services/events${suffix}`); - } - - listCommerceCapacityListings(filters: Record = {}) { - const query = new URLSearchParams(Object.entries(filters).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)])); - const suffix = query.toString() ? `?${query.toString()}` : ''; - return this.request('GET', `/v1/commerce/capacity-listings${suffix}`); - } - - getCommerceCapacityListing(listingId: string) { - return this.request('GET', `/v1/commerce/capacity-listings/${encodeURIComponent(listingId)}`); - } - - getCommerceCapacityListingForProduct(productId: string) { - return this.request('GET', `/v1/commerce/products/${encodeURIComponent(productId)}/capacity-listing`); - } - - createCommerceCapacityListing(productId: string, body: Record) { - return this.request('POST', `/v1/commerce/products/${encodeURIComponent(productId)}/capacity-listing`, { body }); - } - - updateCommerceCapacityListing(listingId: string, body: Record) { - return this.request('PATCH', `/v1/commerce/capacity-listings/${encodeURIComponent(listingId)}`, { body }); - } - - submitCommerceCapacityListing(listingId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/capacity-listings/${encodeURIComponent(listingId)}/submit`, { body }); - } - - approveCommerceCapacityListing(listingId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/capacity-listings/${encodeURIComponent(listingId)}/approve`, { body }); - } - - rejectCommerceCapacityListing(listingId: string, body: Record = {}) { - return this.request('POST', `/v1/commerce/capacity-listings/${encodeURIComponent(listingId)}/reject`, { body }); - } - - suspendCommerceCapacityListing(listingId: string, body: Record
+ Live development Local source - last updated: +