diff --git a/.claude/skills/deploy/SKILL.md b/.claude/skills/deploy/SKILL.md index fabc83fc3..c6e476541 100644 --- a/.claude/skills/deploy/SKILL.md +++ b/.claude/skills/deploy/SKILL.md @@ -77,7 +77,7 @@ If gcloud auth fails with `Reauthentication failed` or `cannot prompt during non | Docker push fails | Check Docker auth: `gcloud auth configure-docker us-east1-docker.pkg.dev`. If network error, retry. | | `ZONE_RESOURCE_POOL_EXHAUSTED` | GCE has no capacity in `us-east1-c`. Wait 10-30 min and retry — GCE capacity is transient. If persistent, try changing machine type in deploy.sh (n2-standard-2 uses a different capacity pool than e2-medium). | | No running instance after 160s | GCE capacity exhausted in all zones. Wait and retry, or manually create in a different zone. | -| Static IP assignment fails | Script retries 3 times. If still fails, the old instance may still hold the IP — wait 30s for MIG replacement. Static IP only works in us-east1 zones. | +| Static IP assignment fails | Script retries 8 times (~330s total budget including 180s pre-flight) and re-resolves the MIG instance name on every retry to defeat the mid-loop-roll variant. If still fails, follow the manual recovery commands printed at end-of-step 7. Static IP only works in us-east1 zones. | | Health check fails via SSH | Container may still be starting — wait 60s and check again. If DB shows ETIMEDOUT, the static IP `34.26.70.60` may not be in Cloud SQL whitelist | | Two instances running | Multiple MIGs may exist. The script finds the first RUNNING instance regardless of zone. If stale MIGs are found, delete them: `gcloud compute instance-groups managed delete super-legal-staging --zone= --quiet` | | SSH `REMOTE HOST IDENTIFICATION HAS CHANGED` | Instance was replaced — new host key. Script clears these automatically, but if manual SSH is needed: `sed -i '' '/compute\./d' ~/.ssh/google_compute_known_hosts` | @@ -124,54 +124,47 @@ gcloud compute ssh super-legal-staging-XXXX --zone=us-east1-c \ ``` Wait 60s, then verify via `curl http://34.26.70.60:3001/health | jq '.reconciliation'` — `error` field should disappear. -### Static IP assignment race (recurring) +### Static IP assignment race (recurring — two distinct failure modes) -**Observed on**: 2026-04-27 v6.7.0 deploy AND 2026-04-28 v6.8.0 deploy. +The script handles two related race conditions in Step 7. Both have hit production multiple times; both fixes are now in `deploy.sh`. -**Symptom**: Step 7 reports `Failed to assign static IP after N attempts`. Container ends up on an ephemeral IP (e.g., `34.23.108.165`). Cloud SQL whitelist only includes `34.26.70.60`, so `ensureHookSchema()` fails. +#### Pattern A — OLD instance still holds the IP -**Root cause**: GCE Managed Instance Group terminates the OLD instance and creates the NEW one in parallel. The OLD instance still holds `34.26.70.60` for ~30-60s during graceful termination. The script's previous retry budget (3 attempts × 15s wait = 45s window) was too short. +**Observed on**: 2026-04-27 v6.7.0, 2026-04-28 v6.8.0. -**Fix in deploy.sh** (Step 7, applied 2026-04-28): -1. Pre-flight wait: poll `gcloud compute addresses list --filter="address=$STATIC_IP"` until status is `RESERVED` (not `IN_USE`). Up to 90s window. -2. Bumped retry attempts from 3 → 5 with 30s wait (total: 150s). -3. Captured stderr to a tempfile so failures surface in the log instead of being silently swallowed by `2>/dev/null`. -4. On final failure, print the manual recovery commands directly to stderr. +**Symptom**: Step 7 retries fail because the OLD instance still has `34.26.70.60` bound during its graceful-termination window (~30-60s). -**Manual recovery if step 7 still fails**: -```bash -INSTANCE=$(gcloud compute instances list --filter="name~super-legal-staging" --format="value(name)" | head -1) -gcloud compute instances delete-access-config $INSTANCE --zone=us-east1-c --access-config-name=external-nat --quiet -sleep 10 -gcloud compute instances add-access-config $INSTANCE --zone=us-east1-c --access-config-name=external-nat --address=34.26.70.60 --quiet -gcloud compute ssh $INSTANCE --zone=us-east1-c --command='docker restart $(docker ps -q | head -1)' -``` +**Fix in deploy.sh** (applied 2026-04-28, widened 2026-05-16): +1. Pre-flight: poll `gcloud compute addresses list --filter="address=$STATIC_IP"` until status is `RESERVED` (not `IN_USE`). **12 × 15s = 180s window** (was 9 × 10s = 90s). +2. Per-retry: 15s sleep between `delete-access-config` and `add-access-config` (was 5s — matches the duration that consistently works in manual recovery). +3. Captured stderr to a tempfile so failures surface in the log. -### Variant: MIG instance replacement mid-retries +#### Pattern B — MIG rolls the instance mid-retry-loop -**Observed on**: 2026-05-06 v7.0.1 deploy. +**Observed on**: 2026-05-06 v7.0.1, then THREE consecutive deploys 2026-05-12 / 2026-05-15 / 2026-05-16. -**Symptom**: Step 7 retries 5x with `Could not fetch resource: super-legal-staging-XXXX` even though the script logs `IP is RESERVED` and proceeds to `Attempt 1/5: Assigning ...`. The log line keeps showing the SAME instance name across all 5 attempts. Meanwhile, `gcloud compute instances list` reveals a DIFFERENT instance name is actually running. +**Symptom**: Script logs `IP is RESERVED` then `Attempt 1/N: Assigning ` — but the log keeps targeting the SAME `` across all retries while `gcloud compute instances list` shows a DIFFERENT running instance. Every `add-access-config` returns `Could not fetch resource: `. -**Root cause**: The MIG terminated the instance the script was targeting (e.g., `super-legal-staging-0239`) and rolled forward to a new one (e.g., `super-legal-staging-bzx4`) DURING step 7's retry budget. The script captured the original instance name in step 6 and did not re-resolve it on each retry. Every `add-access-config` call hits a deleted resource. +**Root cause**: MIG terminated the instance the script captured in Step 6 and rolled to a new one DURING Step 7's retry budget. The script's `$INSTANCE` variable was stale. -**Detection between retries**: -```bash -gcloud compute instances list --filter='name~super-legal-staging AND status=RUNNING' --format='value(name)' -``` -If this returns a different instance name than what the script's log shows, the variant has triggered. +**Fix in deploy.sh** (applied 2026-05-16): +1. **Re-resolve `$INSTANCE` on EVERY retry iteration** via a `resolve_current_instance()` helper that queries `gcloud compute instances list --filter='name~super-legal-staging AND status=RUNNING'`. The script now re-targets and logs `MIG rolled: — re-targeting` whenever the name changes between iterations. +2. **On "Could not fetch resource" errors specifically**, sleep 10s (not 30s) before re-resolving — fast recovery on the most common transient. +3. **Bumped retries 5 → 8** with re-resolution on each, expanding the wall budget from 150s to ~330s (with 180s pre-flight). Total step 7 budget: ~510s (~8.5 min). +4. **Updated manual recovery commands** in the failure message to re-resolve `INSTANCE` first (was using whatever the script had cached). + +#### Manual recovery if Step 7 still exhausts both budgets -**Manual recovery on the new instance**: ```bash -NEW_INSTANCE=$(gcloud compute instances list --filter='name~super-legal-staging AND status=RUNNING' --format='value(name)' | head -1) -gcloud compute instances delete-access-config $NEW_INSTANCE --zone=us-east1-c --access-config-name=external-nat --quiet -sleep 10 -gcloud compute instances add-access-config $NEW_INSTANCE --zone=us-east1-c --access-config-name=external-nat --address=34.26.70.60 --quiet -sed -i '' '/compute\./d' ~/.ssh/google_compute_known_hosts -gcloud compute ssh $NEW_INSTANCE --zone=us-east1-c --command='docker restart $(docker ps -q | head -1)' +INSTANCE=$(gcloud compute instances list --filter='name~super-legal-staging AND status=RUNNING' --format='value(name)' | head -1) +gcloud compute instances delete-access-config $INSTANCE --zone=us-east1-c --access-config-name=external-nat --quiet +sleep 15 +gcloud compute instances add-access-config $INSTANCE --zone=us-east1-c --access-config-name=external-nat --address=34.26.70.60 --quiet +sed -i '' '/compute\./d' ~/.ssh/google_compute_known_hosts # if SSH balks at host-key change +gcloud compute ssh $INSTANCE --zone=us-east1-c --command='docker restart $(docker ps -q | head -1)' ``` -Wait 60s, then verify via `curl http://34.26.70.60:3001/health`. +Wait 60s, then verify via `curl http://34.26.70.60:3001/health | jq '.dependencies.database'`. `status: "ok"` confirms the static-IP + Cloud-SQL-whitelist path is working again. **Future deploy.sh hardening** (not yet implemented): Step 7's retry loop should re-resolve the instance name on each attempt: ```bash diff --git a/.claude/skills/deploy/scripts/deploy.sh b/.claude/skills/deploy/scripts/deploy.sh index 9efdc4850..7a88e38bc 100755 --- a/.claude/skills/deploy/scripts/deploy.sh +++ b/.claude/skills/deploy/scripts/deploy.sh @@ -142,22 +142,31 @@ log "Ensuring firewall tags on $INSTANCE..." gcloud compute instances add-tags "$INSTANCE" --zone="$INSTANCE_ZONE" --tags=super-legal-mcp 2>/dev/null || true # ── Step 7: Assign static IP ──────────────────────────────────────────── -# The recurring failure mode (observed v6.7.0 + v6.8.0): MIG terminates the -# OLD instance and creates the new one in parallel; the OLD instance still -# holds 34.26.70.60 for ~30-60s during graceful termination. Trying to assign -# the static IP to the NEW instance during that window fails with errors -# silently swallowed by 2>/dev/null. Three fixes applied: -# 1) Pre-flight: poll until the address resource shows status=RESERVED -# (or no users), proving the previous instance has fully released it. -# 2) Bumped retries 3→5 with 30s waits (total window 150s vs old 45s). -# 3) Captured stderr to a file so failure messages surface in the log. +# Two recurring failure modes (Apr–May 2026): +# A) Race (v6.7.0, v6.8.0): MIG terminates OLD instance + creates NEW one +# in parallel; OLD still holds 34.26.70.60 for ~30-60s during graceful +# termination. add-access-config to NEW conflicts. +# B) Stale INSTANCE handle (v7.0.1, 2026-05-12, 2026-05-15, 2026-05-16): +# MIG rolls the instance AGAIN during retry budget. Script captured +# $INSTANCE in step 6; every retry hammers a dead resource and gets +# "Could not fetch resource: ". Hit 3× in a row May 2026. +# +# Fixes applied (2026-05-16 — closes pattern B): +# 1) Pre-flight: 12 × 15s = 180s waiting for status=RESERVED (was 90s). +# 2) Re-resolve $INSTANCE from MIG on EVERY retry iteration (the manual +# recovery does this implicitly; the script did not). +# 3) Bumped retries 5 → 8, sleep 5 → 15 between delete+add (matches the +# sleep duration that consistently works in manual recovery). +# 4) On "Could not fetch resource" specifically, log it as a roll-event +# and re-resolve before next retry without waiting the full 30s. +# 5) Captured stderr to a file so failure messages surface in the log. step "Step 7: Assign static IP ($STATIC_IP)" # Pre-flight: wait for the static address to be released by the old instance. -# Up to 90s window — covers GCE graceful-termination latency. +# Up to 180s window — covers GCE graceful-termination latency + 2nd MIG roll. log "Pre-flight: waiting for $STATIC_IP to be released by previous instance..." RELEASED=false -for wait_attempt in 1 2 3 4 5 6 7 8 9; do +for wait_attempt in 1 2 3 4 5 6 7 8 9 10 11 12; do ADDR_STATUS=$(gcloud compute addresses list \ --filter="address=$STATIC_IP" \ --format="value(status,users)" 2>/dev/null | head -1) @@ -167,42 +176,72 @@ for wait_attempt in 1 2 3 4 5 6 7 8 9; do RELEASED=true break fi - log " attempt $wait_attempt: $ADDR_STATUS" - sleep 10 + log " attempt $wait_attempt/12: $ADDR_STATUS" + sleep 15 done if [ "$RELEASED" = false ]; then - warn "Static IP still bound after 90s — proceeding anyway" + warn "Static IP still bound after 180s — proceeding anyway" fi +# Helper: re-resolve the current running MIG instance name. Returns empty if +# nothing is RUNNING. Used at every retry to defeat pattern B. +resolve_current_instance() { + gcloud compute instances list \ + --filter="name~super-legal-staging AND status=RUNNING" \ + --format="value(name)" 2>/dev/null | head -1 +} + ASSIGNED=false ERR_FILE=$(mktemp) trap 'rm -f "$ERR_FILE"' EXIT -for attempt in 1 2 3 4 5; do - log "Attempt $attempt/5: Assigning $STATIC_IP to $INSTANCE..." +for attempt in 1 2 3 4 5 6 7 8; do + # Re-resolve INSTANCE on every iteration — protects against MIG rolling + # mid-loop (pattern B). $INSTANCE_ZONE assumed stable (single-zone MIG). + CURRENT_INSTANCE=$(resolve_current_instance) + if [ -z "$CURRENT_INSTANCE" ]; then + warn " attempt $attempt/8: no RUNNING instance found — MIG may be rolling, waiting 20s" + sleep 20 + continue + fi + if [ "$CURRENT_INSTANCE" != "$INSTANCE" ]; then + log " MIG rolled: $INSTANCE → $CURRENT_INSTANCE — re-targeting" + INSTANCE="$CURRENT_INSTANCE" + fi + log "Attempt $attempt/8: Assigning $STATIC_IP to $INSTANCE..." # Remove existing access config if present (try lowercase first, fallback uppercase) gcloud compute instances delete-access-config "$INSTANCE" --zone="$INSTANCE_ZONE" \ --access-config-name="external-nat" --quiet 2>/dev/null || \ gcloud compute instances delete-access-config "$INSTANCE" --zone="$INSTANCE_ZONE" \ --access-config-name="External NAT" --quiet 2>/dev/null || true - sleep 5 # let the delete propagate before re-adding + sleep 15 # let the delete propagate; 5s was too short, 10–15s consistently works if gcloud compute instances add-access-config "$INSTANCE" --zone="$INSTANCE_ZONE" \ --access-config-name="external-nat" --address="$STATIC_IP" 2>"$ERR_FILE"; then log "Static IP assigned successfully" ASSIGNED=true break fi - warn " failure: $(head -1 "$ERR_FILE")" - warn " retrying in 30s..." - sleep 30 + ERR_MSG=$(head -1 "$ERR_FILE") + warn " failure: $ERR_MSG" + # Pattern B detection: "Could not fetch resource" usually means $INSTANCE + # was deleted by MIG mid-call. Re-resolve on the next iteration immediately + # rather than waiting the full 30s. + if echo "$ERR_MSG" | grep -q "Could not fetch resource"; then + warn " → likely MIG rolled the instance; re-resolving in 10s" + sleep 10 + else + warn " retrying in 30s..." + sleep 30 + fi done if [ "$ASSIGNED" = false ]; then - err "Failed to assign static IP after 5 attempts (total wait: 150s + 90s pre-flight)" - warn "Manual recovery — run these commands:" - warn " gcloud compute instances delete-access-config $INSTANCE --zone=$INSTANCE_ZONE --access-config-name=external-nat --quiet" - warn " sleep 10" - warn " gcloud compute instances add-access-config $INSTANCE --zone=$INSTANCE_ZONE --access-config-name=external-nat --address=$STATIC_IP --quiet" - warn " gcloud compute ssh $INSTANCE --zone=$INSTANCE_ZONE --command='docker restart \$(docker ps -q | head -1)'" + err "Failed to assign static IP after 8 attempts (~330s total: 180s pre-flight + 8 retries)" + warn "Manual recovery — run these commands (re-resolve INSTANCE first):" + warn " INSTANCE=\$(gcloud compute instances list --filter='name~super-legal-staging AND status=RUNNING' --format='value(name)' | head -1)" + warn " gcloud compute instances delete-access-config \$INSTANCE --zone=$INSTANCE_ZONE --access-config-name=external-nat --quiet" + warn " sleep 15" + warn " gcloud compute instances add-access-config \$INSTANCE --zone=$INSTANCE_ZONE --access-config-name=external-nat --address=$STATIC_IP --quiet" + warn " gcloud compute ssh \$INSTANCE --zone=$INSTANCE_ZONE --command='docker restart \$(docker ps -q | head -1)'" FINAL_IP=$(gcloud compute instances describe "$INSTANCE" --zone="$INSTANCE_ZONE" \ --format="value(networkInterfaces[0].accessConfigs[0].natIP)" 2>/dev/null) warn "Using ephemeral IP: $FINAL_IP" diff --git a/super-legal-mcp-refactored/docs/pending-updates/excel-workbook-issues.md b/super-legal-mcp-refactored/docs/pending-updates/excel-workbook-issues.md new file mode 100644 index 000000000..ae598a435 --- /dev/null +++ b/super-legal-mcp-refactored/docs/pending-updates/excel-workbook-issues.md @@ -0,0 +1,251 @@ +# Excel Workbook Architecture Issues — Forward Plan + +**Status**: PENDING REVIEW — pre-implementation spec +**Author note (2026-05-16)**: surfaced via candid architectural review after PRs #134-#143 shipped the LLM-driven xlsx renderer + supporting infrastructure +**Related GitHub issue**: (to be filed alongside this doc) +**Risk if ignored**: ~$120K/year ongoing cost for a workflow that may not warrant LLM-driven generation + +--- + +## §1 — Context + +Over PRs #134-#143 (Avenue B Phase 1 → operator-runbook readiness → `xlsx-workbook-template-creator` skill → skill content gaps), we shipped: + +- LLM-driven xlsx renderer that invokes `runPythonAnalysis` to generate openpyxl Python per render +- Avenue A v2 envelope schema enforcement (`ENVELOPE_SCHEMA_XLSX`, Option A audit-only pivot) +- Multi-turn phase orchestrator (`multiTurnOrchestrator.js`) with phase fan-out via `pLimit(5)` +- `selectEnvelopeWithFallback` extraction logic (parsed_output → text → stdout → merge) +- Generic envelope-outcome Prometheus counter + 6 alerts +- Cloud Logging structured `envelope_decision` event +- OTel span attributes for `envelope_source` + `caller_category` +- `xlsx_renders` table state machine + dual-path schema +- `access_log.event_data` JSONB enrichment + `code_executions.envelope_source` column +- `xlsx-workbook-template-creator` skill (scaffolder + validator + 7 reference docs) +- Canonical templates README + prompts README (~750 LOC) +- Operator runbook (alerts + cohort plan + debug playbook) +- Feature flag truth doc registration (#41 XLSX_RENDERER + #42 STRUCTURED_OUTPUT_ENFORCEMENT) + +**Critical**: `XLSX_RENDERER` flag is still `false` in production. No xlsx renders are currently happening for any client. + +## §2 — Issue summary + +The xlsx renderer pays approximately **$5-10 per render** to have the LLM regenerate openpyxl Python that maps already-computed subagent data into already-declared template layouts. At expected production scale (~50 renders/day × $7 average × 365 days), this is **~$120K/year of ongoing cost**. + +**The redundancy**: + +1. Subagents (`financial-analyst`, `tax-structure-analyst`, etc.) run analyses via `run_python_analysis` during orchestration. The Python computes (e.g.) DCF, comps, LBO returns. Results persist to `code_executions` rows. +2. After orchestration finishes, the xlsx renderer invokes `run_python_analysis` **a second time** for each phase. The model writes openpyxl Python that: + - Reads the data the first execution already computed (now persisted as JSON in `code_executions.data`) + - Maps that data into Excel cells with formulas + formatting + - Applies cell coloring discipline + Sources sheet entries + - Emits b64-encoded xlsx file + audit envelope + +The analysis is already done. The model is being asked to translate **declarative template specs** (which layout, which formula style, which cell colors, which audit rules — ALL specified in the template config) into **imperative Python** that implements those specs. The audit checks then verify the model matched what was declared. + +**The model is paid to do work the template declaration already did.** + +## §3 — What the model genuinely adds vs what's redundant + +| Workbook content | LLM-required? | Could be deterministic Python? | +|---|---|---| +| Cover narrative prose | ✅ Yes (deal-specific text synthesis) | ❌ Templated prose would be generic | +| Executive summary text | ✅ Yes (cross-subagent synthesis) | ⚠️ Partially templated | +| Assumptions table (5-col) | ❌ No | ✅ Trivial openpyxl | +| 3-statement model | ❌ No | ✅ Data + formula templates | +| DCF tab | ❌ No | ✅ Standard NPV/IRR formulas | +| Comps table | ❌ No | ✅ 7-col data table | +| LBO sub-sheets | ❌ No | ✅ Standard LBO template | +| Sensitivity 2D heatmap | ❌ No | ✅ Programmatic from sensitivity data | +| Sources index | ❌ No | ✅ Deterministic from citations | +| Model index (session-models) | ❌ No | ✅ Programmatic from `code_executions` | +| Risk register | ⚠️ Maybe (narrative descriptions) | ⚠️ Mostly programmatic + short descriptions | +| Cell coloring discipline | ❌ No | ✅ Programmatic rules | +| Audit checks (formula whitelist, balance, sources) | ❌ No | ✅ Better deterministic than LLM self-attestation | + +**~80-90% of per-render compute is mechanical data formatting** that does not require LLM. Only narrative content (cover, exec_summary, possibly risk register descriptions) genuinely requires LLM. + +## §4 — Root cause analysis + +This architecture appears to have emerged via path dependency, not design optimization: + +1. **Subagents were designed first**. Their bridge integration (`run_python_analysis` for analysis output) shipped before xlsx requirements existed. +2. **xlsx requirements arrived later**. The bridge was the familiar tool; reaching for it for xlsx generation was the line of least resistance. +3. **Once LLM-driven, complexity accumulated** to manage the resulting brittleness: + - PR #135 Avenue A v2 to enforce envelope shape via Anthropic API (added because envelope corruption was common) + - PR #135 Option A pivot to scope `b64_xlsx` to stdout-only (added because MAX_TOKENS cliff broke phase3 LBO at L4 v1) + - PR #134 Path B (no cross-phase chaining) to enable parallel phases + - PR #138 observability v2 to make envelope failures debuggable + - PR #140 operator runbook + 6 alerts to gate the production flag flip +4. **Templates evolved to be declarative**. PR #143's templates README catalogs 12 layouts + 3 trigger fields + canonical `XLSX_TEMPLATE_BASE` (PRE_2019_FUNCTIONS, CELL_COLORING, SOURCES_SHEET_SPEC, AUDIT_CHECKS). These declarations describe what the workbook should look like with high specificity. +5. **The audit checks verify** the model matched declarative specs (no_hardcodes_in_formulas, sources_sheet_complete, named_ranges_resolve, balance_check). The audit's existence implies the spec already describes the truth. + +If templates were highly variable (one-off per client, unpredictable layouts), LLM-driven generation would justify the cost. But our 5 production templates use the same 12 layouts repeatedly. **Variability is low; the LLM flexibility tax is paying for unused flexibility.** + +## §5 — Proposed solution: subagent-emitted workbook fragments + deterministic merger + +### Architecture change + +Replace the LLM-driven xlsx renderer with a **single module** where: + +1. Each subagent's `run_python_analysis` invocation **also emits a workbook fragment** alongside analysis + charts. The Python that computes the DCF (using data already in memory) also writes the DCF tab. Marginal cost: ~$0.05 per subagent call (incremental Python execution, no new bridge call). + +2. **Post-orchestration merger** (deterministic Node code, no LLM): + - Reads `code_executions` rows for the session + - Collects each row's `workbook_fragment_b64` (new field on envelope or stored in existing `data` JSONB) + - Merges fragments into a single workbook using openpyxl + - Applies unified Sources sheet (all citations from all subagents) + - Validates audit checks programmatically (formula whitelist, balance, sources) + - Persists to `xlsx_renders` + +3. **ONE bridge call** for cover + exec_summary narrative prose (cross-session synthesis that genuinely requires LLM). Cost: ~$0.10-0.30. + +### Cost-benefit + +| Metric | Current (LLM-driven) | Proposed (unified) | Reduction | +|---|---|---|---| +| Bridge calls per session | ~10-15 (N subagent + 5 render phases) | ~N subagent + 0-1 narrative | ~70% | +| Cost per render | $5-10 | $0.30-0.50 | **~95%** | +| Wall-clock per render | 4-5 min (parallel phases) | seconds (deterministic) | **~95%** | +| Annual cost at scale | ~$120K | ~$5-10K | **~95%** | +| Maintenance LOC | 9 PRs of supporting infra | merger + 1 prose prompt | substantial | +| Failure modes | max_tokens cliffs, envelope corruption, retry budgets, audit divergence | per-subagent (already handled by Agent SDK) | fewer | + +### What this RETIRES (no longer needed) + +- Avenue A v2 envelope enforcement (PR #135) — no envelope schema needed for deterministic generator +- `ENVELOPE_SCHEMA_XLSX` + Option A merge logic (PR #135) — not needed +- `selectEnvelopeWithFallback` xlsx branches (PR #138) — not needed +- `STRUCTURED_OUTPUT_ENFORCEMENT` flag (#42) — not needed +- 6 Prometheus alerts on envelope counters (PR #140) — not needed +- `envelope-decision-debug-playbook.md` (PR #140) — not needed +- `structured-output-enforcement-rollout.md` cohort plan (PR #140) — not needed +- `multiTurnOrchestrator.js` phase fan-out (PR #134) — replaced by simple per-row collection +- Most of `xlsx-workbook-template-creator` skill (PRs #142, #143) — much simpler: scaffold merge spec + narrative prompt + +### What this PRESERVES (still valuable) + +- Post-orchestration trigger architecture (re-invocability, failure isolation, manual API) +- `selectTemplate(sessionContext)` dispatch (template selection by triggers) +- `xlsx_renders` table state machine + dual-path schema +- Generic `claude_code_bridge_envelope_outcome_total` Prometheus counter (still emitted by subagent bridge calls — different `caller_category`) +- `envelope_source` column on `code_executions` (still useful for subagent invocations) +- `access_log.event_data` JSONB enrichment (still useful for forensic queries) +- Structured `envelope_decision` Cloud Logging events (still useful) +- Truth doc registration (XLSX_RENDERER #41 stays; STRUCTURED_OUTPUT_ENFORCEMENT #42 is retired) +- Operator skill enhancements (post-deploy-verify V7 check, infrastructure-health postgresql.md, etc.) +- Compliance audit trail (Art. 12/13/14) + +## §6 — Migration plan (4 phases) + +### Phase 0: Decision + risk assessment + +- Review this spec +- File companion GitHub issue (roadmap) +- Architecture lead decision: redesign vs proceed? +- If proceed-as-is: at minimum, do NOT flip `XLSX_RENDERER=true` in production until economics validated against real data +- If redesign: assign Phase 1 owner + 2-week timeline + +### Phase 1: Prototype unified module (one template) + +- Pick simplest template (`session-models` fallback) as proof of concept +- Augment `financial-analyst` subagent prompt to emit `workbook_fragment_b64` (alongside `analysis`/`data`/`charts`) +- Build deterministic Node merger for `session-models` layout (single auto-per-model tab + sources) +- Validate: side-by-side comparison vs current LLM-generated workbook for 5 sample sessions +- Measure: actual cost, actual wall-clock, audit pass rate + +### Phase 2: Migrate per template (4 production templates remaining) + +Once prototype validated: +- Migrate one template at a time: `valuation-only` → `tax-memo-workbook` → `full-deal-workbook` → `lbo-focused` +- Per-template feature flag for dispatcher (`UNIFIED_XLSX_=true`) +- Side-by-side comparison: render same session both ways, compare workbook quality +- Switch dispatcher when satisfied; keep LLM path callable via flag override for fallback + +### Phase 3: Retire LLM renderer infrastructure + +Once all 5 templates migrated to unified design: +- Delete `multiTurnOrchestrator.js` phase fan-out (or reduce to thin shim) +- Delete `ENVELOPE_SCHEMA_XLSX` + xlsx-mode merge logic in `selectEnvelopeWithFallback` +- Remove `STRUCTURED_OUTPUT_ENFORCEMENT` flag from `featureFlags.js`, `flags.env`, truth doc §42 +- Remove 6 envelope-counter alerts from `prometheus/alerts.yml` +- Archive `envelope-decision-debug-playbook.md` and `structured-output-enforcement-rollout.md` (move to `docs/archive/`) +- Simplify `xlsx-workbook-template-creator` skill: scaffold becomes merge-spec + narrative-prompt structure + +### Phase 4: Re-evaluate operator skills + final cleanup + +- Some operator skills still useful (post-deploy-verify V7 check probes the generic counter, which still emits) +- Some become moot (envelope-decision playbook — archive) +- Update CHANGELOG + docs to reflect new architecture +- Final cost validation: 30 days of production data showing ~$5-10K/year actual + +## §7 — Open questions (need decisions before Phase 1) + +1. **Fragment format**: what's the canonical `workbook_fragment_b64` format? + - Option A: base64 of a single-tab openpyxl `.xlsx` file (merger uses `openpyxl.load_workbook` + copy_worksheet) + - Option B: JSON spec describing cells, formulas, styles (merger constructs openpyxl from JSON) + - Tradeoff: A is simpler for the subagent (just save+encode); B is easier for the merger to recompose into different layouts + +2. **Template variability**: do future templates need flexibility a deterministic generator can't provide? + - Threshold: if new layouts per quarter > 1, deterministic generator becomes maintenance burden + - Current trajectory: ~0 new templates in last 6 months; product team adds new ones rarely + +3. **Re-rendering historical sessions with NEW templates**: + - Current design: templates can be updated and old sessions re-rendered using same `code_executions` data + - Unified design challenge: fragments are baked at session time with old layout assumptions + - Options: (a) merger supports fragment-to-template remapping (complex); (b) re-rendering requires re-running orchestration (expensive — defeats one of the benefits we kept) + - Need to decide before Phase 1 whether re-rendering capability is non-negotiable + +4. **Subagent prompt bloat**: each subagent prompt gets longer with fragment-emission instructions + - Token budget impact: ~500-1000 tokens per subagent system prompt + - Cache-able (prompt prefix doesn't vary per session) + +5. **Cover + exec_summary cross-session synthesis**: ONE bridge call needs ALL subagent outputs as context + - Prompt construction: how do we serialize N subagent outputs into one prompt without exceeding context? + - Options: (a) summarize each subagent output to <1KB; (b) selective context based on template needs + +6. **XLSX_RENDERER flag flip decision**: should we proceed with the current LLM-driven production rollout per PR #140 runbook? + - If we expect to migrate to unified design: flipping the LLM version to production wastes operator effort + accumulates cost + - If migration is uncertain: flipping is the safe bet (preserves operator path) + - Recommendation pending architecture review decision + +## §8 — Honest framing + +This plan was written following a candid architectural discussion on 2026-05-16 in which the original implementation author admitted, through several rounds of correction by the reviewer, that: + +1. The "latency" arguments for the current design (post-orchestration vs in-orchestration) were overstated — 4-5 min wall-clock gap is noise on a 4-6 hour pipeline +2. The "failure isolation" argument is real but solvable in either design +3. The CORE redundancy (LLM regenerating Python to format already-computed data) was not articulated in any of the 9 PRs that shipped this design +4. The 9-PR chain (#134-#143) built reliability infrastructure around a workflow whose foundational architectural choice may not have warranted the LLM in the first place for ~80-90% of its work + +**This is NOT a critique of the engineering work in PRs #134-#143.** Each PR was well-executed for its stated scope. Avenue A v2 envelope enforcement, observability v2, operator runbook, skill scaffolding, and content gap closure all delivered their stated goals. + +**This IS an architectural review**: the right level of abstraction may not have been chosen at design time. We built Bridge Engineering Excellence (observability, alerts, runbooks, skills) around an LLM-driven workflow that maybe should have been deterministic Python with a single narrative LLM call. + +The work shipped is not wasted — most of the observability infrastructure remains useful for ANY bridge invocation pattern. But the LLM-driven xlsx generation specifically may warrant replacement before scaling cost commits us to $120K/year of ongoing LLM compute for what's largely mechanical work. + +## §9 — Related PRs (the chain that may need to be partially unwound) + +| PR | Scope | Status | Impact under unified design | +|---|---|---|---| +| #134 | Avenue B Phase 1 sensitivity isolation | MERGED | Retired (no phase fan-out needed) | +| #135 | Avenue A v2 structured output enforcement | MERGED | Retired (no envelope schema needed) | +| #136 | Per-template + per-phase counter | MERGED | Retired (no per-phase concept) | +| #137 | Skills posture docs | MERGED | Preserved (architectural posture still valid) | +| #138 | Bridge observability v2 | MERGED | Preserved (still useful for subagent calls) | +| #139 | PR #138 real-bug followup | MERGED | Preserved | +| #140 | Operator runbook readiness | MERGED | Partially retired (envelope alerts + playbook archive) | +| #141 | Skill doc companion | MERGED | Preserved (mostly) | +| #142 | xlsx-workbook-template-creator skill | MERGED | Substantially simplified | +| #143 | Skill content gaps + canonical READMEs | MERGED | Templates README preserved; skill simplified | + +## §10 — Recommended next steps + +1. **Read this spec + GitHub issue** (companion to this doc) +2. **Architecture review meeting** to decide: redesign or proceed? +3. **DO NOT flip `XLSX_RENDERER=true` in production** until decision is made — currently no production sessions render workbooks, so cost is $0; flipping commits to ~$120K/year baseline that this spec proposes to avoid +4. **If redesign approved**: Phase 0 → Phase 4 per §6, estimated 6-8 week implementation +5. **If proceed-as-is approved**: at minimum document why the cost was accepted; consider gradual rollout to validate cost projections + +--- + +**End of spec.** Companion GitHub issue tracks the roadmap of concerns + decision points. diff --git a/super-legal-mcp-refactored/package-lock.json b/super-legal-mcp-refactored/package-lock.json index d9e77d438..f3cb8a1cf 100644 --- a/super-legal-mcp-refactored/package-lock.json +++ b/super-legal-mcp-refactored/package-lock.json @@ -27,11 +27,13 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "dotenv": "^16.6.1", + "exceljs": "^4.4.0", "express": "^4.19.2", "jsonwebtoken": "^9.0.3", "multer": "^2.0.2", "node-cron": "^4.2.1", "node-pg-migrate": "^8.0.4", + "p-limit": "^6.2.0", "pdfjs-dist": "^3.11.174", "pg": "^8.11.3", "pgvector": "^0.2.1", @@ -775,6 +777,47 @@ "dev": true, "license": "MIT" }, + "node_modules/@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "license": "MIT", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "node_modules/@fast-csv/format/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "license": "MIT" + }, + "node_modules/@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "license": "MIT", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/@fast-csv/parse/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "license": "MIT" + }, "node_modules/@google-cloud/paginator": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", @@ -994,6 +1037,21 @@ } } }, + "node_modules/@google-cloud/storage/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@google-cloud/storage/node_modules/retry-request": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", @@ -1050,6 +1108,18 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/@google-cloud/storage/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@google/genai": { "version": "1.45.0", "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.45.0.tgz", @@ -3967,6 +4037,81 @@ "license": "ISC", "optional": true }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/are-we-there-yet": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", @@ -4007,6 +4152,12 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, "node_modules/async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -4188,6 +4339,15 @@ "node": ">= 18" } }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, "node_modules/bignumber.js": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", @@ -4197,12 +4357,42 @@ "node": "*" } }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "license": "MIT", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, "node_modules/bintrees": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==", "license": "MIT" }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "license": "MIT" + }, "node_modules/body-parser": { "version": "1.20.4", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", @@ -4246,7 +4436,6 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "devOptional": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4310,6 +4499,39 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "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-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -4322,6 +4544,23 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "engines": { + "node": ">=0.2.0" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -4447,6 +4686,18 @@ "node": ">=6" } }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "license": "MIT/X11", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4579,6 +4830,21 @@ "node": ">= 0.8" } }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -4622,7 +4888,6 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "devOptional": true, "license": "MIT" }, "node_modules/concat-stream": { @@ -4709,6 +4974,12 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "license": "MIT" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/cors": { "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", @@ -4726,6 +4997,31 @@ "url": "https://opencollective.com/express" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -4771,6 +5067,12 @@ "node": ">= 12" } }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4927,6 +5229,51 @@ "node": ">= 0.4" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/duplexify": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", @@ -5137,6 +5484,26 @@ "node": ">=18.0.0" } }, + "node_modules/exceljs": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.4.0.tgz", + "integrity": "sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==", + "license": "MIT", + "dependencies": { + "archiver": "^5.0.0", + "dayjs": "^1.8.34", + "fast-csv": "^4.3.1", + "jszip": "^3.10.1", + "readable-stream": "^3.6.0", + "saxes": "^5.0.1", + "tmp": "^0.2.0", + "unzipper": "^0.10.11", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=8.3.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -5257,6 +5624,19 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, + "node_modules/fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "license": "MIT", + "dependencies": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5491,6 +5871,12 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -5543,7 +5929,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "devOptional": true, "license": "ISC" }, "node_modules/fsevents": { @@ -5561,6 +5946,35 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5705,7 +6119,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "devOptional": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -5786,7 +6199,6 @@ "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==", - "dev": true, "license": "ISC" }, "node_modules/gtoken": { @@ -6066,6 +6478,32 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "BSD-3-Clause" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, "node_modules/import-in-the-middle": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.0.1.tgz", @@ -6122,7 +6560,6 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "devOptional": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -6431,6 +6868,35 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-changed-files/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-circus": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", @@ -6463,6 +6929,35 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-circus/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-cli": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", @@ -6805,6 +7300,35 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-runner/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runner/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-runtime": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", @@ -7165,6 +7689,54 @@ "node": ">=10" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/jwa": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", @@ -7206,6 +7778,54 @@ "node": ">=6" } }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -7216,6 +7836,15 @@ "node": ">=6" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -7223,6 +7852,12 @@ "dev": true, "license": "MIT" }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", + "license": "ISC" + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -7242,6 +7877,36 @@ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "license": "MIT" + }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==", + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -7254,12 +7919,31 @@ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "license": "MIT" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "license": "MIT" + }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", "license": "MIT" }, + "node_modules/lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==", + "license": "MIT" + }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", @@ -7278,12 +7962,30 @@ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", "license": "MIT" }, + "node_modules/lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==", + "license": "MIT" + }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "license": "MIT" }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT" + }, "node_modules/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", @@ -7456,7 +8158,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -7817,7 +8518,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7954,15 +8654,15 @@ } }, "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "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": "^0.1.0" + "yocto-queue": "^1.1.1" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8026,6 +8726,12 @@ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -8136,7 +8842,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8426,6 +9131,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, "node_modules/prom-client": { "version": "15.1.3", "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz", @@ -8595,6 +9306,36 @@ "node": ">= 6" } }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8860,6 +9601,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -8940,6 +9693,12 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -9351,6 +10110,22 @@ "node": ">=10" } }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -9424,7 +10199,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.14" @@ -9465,6 +10239,15 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "license": "MIT/X11", + "engines": { + "node": "*" + } + }, "node_modules/ts-algebra": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", @@ -9538,6 +10321,60 @@ "node": ">= 0.8" } }, + "node_modules/unzipper": { + "version": "0.10.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", + "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", + "license": "MIT", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/unzipper/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/unzipper/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -9753,6 +10590,12 @@ } } }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -9821,17 +10664,52 @@ } }, "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/zod": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",