feat(shared-ai): extract planner + mission types to @mana/shared-ai

Single source of truth for AI Workbench types shared between the webapp
(Vite/SvelteKit) and the server-side mana-ai Bun service. Prevents the
two runtimes from drifting on prompt shape or mission structure.

- `@mana/shared-ai` package:
  - `actor.ts` — Actor union (user | ai | system) + helpers, mirrors the
    webapp's runtime type so server-side consumers parse incoming actors
    without re-declaring
  - `missions/types.ts` — Mission, MissionCadence, MissionInputRef,
    MissionIteration, PlanStep, MissionState. Adds optional
    `iteration.source: 'browser' | 'server'` to distinguish foreground
    vs server-produced iterations (groundwork for proposal write-back)
  - `planner/prompt.ts` — `buildPlannerPrompt` pure function
  - `planner/parser.ts` — `parsePlannerResponse` strict JSON validator
  - Vitest smoke tests (2) cover prompt → parse round-trip + unknown-
    tool rejection
- Webapp:
  - `missions/types.ts` re-exports from shared-ai, keeps webapp-local
    `MISSIONS_TABLE` constant + `planStepStatusFromProposal` bridge
  - `missions/planner/{types,prompt,parser}.ts` become re-export stubs
    so existing imports keep working unchanged
  - Existing webapp tests (60) continue to pass — the wire code didn't
    move, just its home

Next: mana-ai service imports buildPlannerPrompt/parsePlannerResponse
from shared-ai + wires mana-llm + writes iteration back as a
'source=server' row (tracked in services/mana-ai/CLAUDE.md).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-15 00:01:57 +02:00
parent 1191952d0f
commit 0d90b12d1c
17 changed files with 778 additions and 679 deletions

View file

@ -53,6 +53,7 @@
"@mana/local-store": "workspace:*",
"@mana/local-stt": "workspace:^",
"@mana/qr-export": "workspace:*",
"@mana/shared-ai": "workspace:*",
"@mana/shared-auth": "workspace:*",
"@mana/shared-auth-ui": "workspace:*",
"@mana/shared-branding": "workspace:*",

View file

@ -1,99 +1,7 @@
/**
* Parser for Planner LLM output.
*
* Strict: we only accept the fenced `json` block the system prompt
* prescribes, validate shape, and surface errors so the Runner can
* record them on the iteration instead of silently producing a bad plan.
* Re-export of the Planner response parser from @mana/shared-ai.
* Kept here so existing webapp imports (and tests) keep working.
*/
import type { AiPlanOutput, PlannedStep } from './types';
export type ParseResult =
| { readonly ok: true; readonly value: AiPlanOutput }
| { readonly ok: false; readonly reason: string; readonly raw?: string };
/** Extract and validate the Planner JSON from the LLM's raw response. */
export function parsePlannerResponse(text: string, knownToolNames: Set<string>): ParseResult {
const block = extractJsonBlock(text);
if (!block) return { ok: false, reason: 'no JSON block found', raw: text };
let parsed: unknown;
try {
parsed = JSON.parse(block);
} catch (err) {
return {
ok: false,
reason: `JSON parse failed: ${err instanceof Error ? err.message : String(err)}`,
raw: block,
};
}
if (typeof parsed !== 'object' || parsed === null) {
return { ok: false, reason: 'top-level value is not an object', raw: block };
}
const obj = parsed as Record<string, unknown>;
const summary = typeof obj.summary === 'string' ? obj.summary : '';
const rawSteps = obj.steps;
if (!Array.isArray(rawSteps)) {
return { ok: false, reason: '`steps` must be an array', raw: block };
}
const steps: PlannedStep[] = [];
for (let i = 0; i < rawSteps.length; i++) {
const step = rawSteps[i];
const validation = validateStep(step, knownToolNames, i);
if (!validation.ok) {
return { ok: false, reason: validation.reason, raw: block };
}
steps.push(validation.value);
}
return { ok: true, value: { summary, steps } };
}
function extractJsonBlock(text: string): string | null {
// Prefer a ```json fenced block
const fenced = /```(?:json)?\s*\n?([\s\S]*?)\n?```/;
const m = text.match(fenced);
if (m) return m[1].trim();
// Fallback: the whole response might BE a JSON object
const trimmed = text.trim();
if (trimmed.startsWith('{') && trimmed.endsWith('}')) return trimmed;
return null;
}
function validateStep(
raw: unknown,
knownToolNames: Set<string>,
index: number
): { ok: true; value: PlannedStep } | { ok: false; reason: string } {
if (typeof raw !== 'object' || raw === null) {
return { ok: false, reason: `step[${index}] is not an object` };
}
const obj = raw as Record<string, unknown>;
const toolName = obj.toolName;
if (typeof toolName !== 'string' || toolName.length === 0) {
return { ok: false, reason: `step[${index}].toolName missing or not a string` };
}
if (!knownToolNames.has(toolName)) {
return {
ok: false,
reason: `step[${index}].toolName "${toolName}" is not in the allowed tool set`,
};
}
const summary = typeof obj.summary === 'string' ? obj.summary : '';
const rationale = typeof obj.rationale === 'string' ? obj.rationale : '';
if (rationale.length === 0) {
return { ok: false, reason: `step[${index}].rationale is required (user will see this)` };
}
const params =
typeof obj.params === 'object' && obj.params !== null
? (obj.params as Record<string, unknown>)
: {};
return {
ok: true,
value: { summary, toolName, rationale, params },
};
}
export { parsePlannerResponse } from '@mana/shared-ai';
export type { ParseResult } from '@mana/shared-ai';

View file

@ -1,112 +1,7 @@
/**
* Prompt builder for the Mission Planner.
*
* Produces a system + user message pair the LLM backend can consume. The
* grammar we ask the model to return is deliberately small (JSON in a
* fenced block, one shape) the parser is strict, and we'd rather the
* LLM mess up in a detectable way than produce half-valid output.
*
* Keeps everything the Planner sees inside the prompt, nothing ambient
* makes the task reproducible and unit-testable without a live LLM.
* Re-export of the Planner prompt builder from @mana/shared-ai.
* Kept here so existing webapp imports (and tests) keep working.
*/
import type { AiPlanInput } from './types';
export interface PlannerMessages {
readonly system: string;
readonly user: string;
}
export function buildPlannerPrompt(input: AiPlanInput): PlannerMessages {
return {
system: buildSystemPrompt(input),
user: buildUserPrompt(input),
};
}
function buildSystemPrompt(input: AiPlanInput): string {
const toolBlock = input.availableTools
.map((t) => {
const params = t.parameters
.map((p) => {
const req = p.required ? ' (required)' : '';
const enumeration = p.enum ? ` [${p.enum.join('|')}]` : '';
return ` - ${p.name}: ${p.type}${enumeration}${req}${p.description}`;
})
.join('\n');
return `${t.name} (${t.module}) — ${t.description}\n${params || ' (no parameters)'}`;
})
.join('\n');
return `Du bist eine KI, die im Auftrag des Nutzers an einer langlebigen Mission arbeitet.
Dein Job: aus dem aktuellen Mission-Kontext einen kurzen, konkreten Plan ableiten 1 bis 5 Schritte, jeder ein Tool-Aufruf auf Nutzerdaten. Jeder Schritt MUSS eine Begründung haben (rationale), die der Nutzer in der Review-UI sieht.
Wichtige Regeln:
1. Nutze NUR Tools aus der Liste unten. Unbekannte Tools Plan invalide.
2. Jeder Step wird als Proposal gestaged der Nutzer approved oder rejected. Du schreibst nie direkt.
3. Berücksichtige das Feedback aus vorherigen Iterationen (unten im User-Prompt). Wenn ein Vorschlag rejected wurde, wiederhole ihn nicht ohne Änderung.
4. Antworte AUSSCHLIESSLICH mit einem JSON-Block in folgendem Format, keine Prosa davor/danach:
\`\`\`json
{
"summary": "Ein Satz was du in dieser Iteration tust.",
"steps": [
{
"summary": "Kurzer Schritt-Titel",
"toolName": "create_task",
"params": { "title": "…" },
"rationale": "Warum genau jetzt, auf Basis welchen Inputs."
}
]
}
\`\`\`
Verfügbare Tools:
${toolBlock || ' (keine Tools verfügbar — gib leeren steps zurück)'}`;
}
function buildUserPrompt(input: AiPlanInput): string {
const { mission, resolvedInputs } = input;
const inputsBlock =
resolvedInputs.length === 0
? '_(keine verlinkten Inputs)_'
: resolvedInputs
.map((r) => {
const header = `### ${r.module}/${r.table}: ${r.title ?? r.id}`;
return `${header}\n${r.content}`;
})
.join('\n\n');
const iterationHistory =
mission.iterations.length === 0
? '_(erste Iteration)_'
: mission.iterations
.slice(-3) // only the last 3 to keep the prompt tight
.map((it) => {
const steps = it.plan.map((s) => ` - [${s.status}] ${s.summary}`).join('\n');
const feedback = it.userFeedback ? `\n Nutzer-Feedback: ${it.userFeedback}` : '';
const summary = it.summary ? `\n Summary: ${it.summary}` : '';
return `**${it.startedAt}** (${it.overallStatus}):${summary}\n${steps}${feedback}`;
})
.join('\n\n');
return `# Mission: ${mission.title}
## Konzept
${mission.conceptMarkdown || '_(leer)_'}
## Konkretes Ziel
${mission.objective}
## Verlinkte Inputs
${inputsBlock}
## Letzte Iterationen (max. 3)
${iterationHistory}
---
Erzeuge jetzt einen Plan für die nächste Iteration.`;
}
export { buildPlannerPrompt } from '@mana/shared-ai';
export type { PlannerMessages } from '@mana/shared-ai';

View file

@ -1,56 +1,12 @@
/**
* Planner contract shared input / output shape used by prompt builder,
* parser, and the `aiPlanTask` LLM wrapper.
* Re-export of Planner types from @mana/shared-ai. The shared package is
* the source of truth webapp and mana-ai service both import from it.
*/
import type { Mission } from '../types';
/** Resolved content for one {@link MissionInputRef}. */
export interface ResolvedInput {
readonly id: string;
readonly module: string;
readonly table: string;
readonly title?: string;
readonly content: string;
}
/** Tool definition the Planner is allowed to propose. */
export interface AvailableTool {
readonly name: string;
readonly module: string;
readonly description: string;
readonly parameters: ReadonlyArray<{
readonly name: string;
readonly type: string;
readonly required: boolean;
readonly description: string;
readonly enum?: readonly string[];
}>;
}
export interface AiPlanInput {
readonly mission: Mission;
/** Content of every MissionInputRef, pre-fetched by the caller (Runner). */
readonly resolvedInputs: readonly ResolvedInput[];
/** Tools the policy has whitelisted for AI proposals in this run. */
readonly availableTools: readonly AvailableTool[];
}
/**
* One step in the Planner's output. The Runner turns each step into a
* Proposal by calling `executeTool(toolName, params, aiActor)` the
* policy routes it to `propose`, and the Proposal carries the rationale.
*/
export interface PlannedStep {
readonly summary: string;
readonly toolName: string;
readonly params: Record<string, unknown>;
readonly rationale: string;
}
export interface AiPlanOutput {
/** 1N steps the AI wants to take this iteration. May be empty (no-op run). */
readonly steps: readonly PlannedStep[];
/** The AI's one-line summary of the plan, stored on `MissionIteration.summary`. */
readonly summary: string;
}
export type {
AiPlanInput,
AiPlanOutput,
AvailableTool,
PlannedStep,
ResolvedInput,
} from '@mana/shared-ai';

View file

@ -1,106 +1,22 @@
/**
* Missions long-lived AI work items.
* Webapp-local re-export of Mission types from @mana/shared-ai plus
* storage-layer concerns (Dexie table name, proposal-status bridge).
*
* A Mission is the user's standing instruction to the AI ("review my goals
* every Monday and propose three concrete actions"). The AI plans, stages
* proposals (via `pendingProposals`), collects feedback, and iterates.
*
* This file is data-model only. The Planner and Runner live elsewhere and
* operate on Missions see `COMPANION_BRAIN_ARCHITECTURE.md §20` for the
* full pipeline.
*
* Missions sync (unlike proposals) they are long-lived user-authored
* artifacts and should be available cross-device. Sensitive user-typed
* text (conceptMarkdown, objective, rationale strings in iterations) is
* encryption-eligible; IDs, timestamps, state enums stay plaintext.
* The runtime types themselves live in the shared package so the
* mana-ai Bun service parses identical rows.
*/
import type { ProposalStatus } from '../proposals/types';
import type { PlanStep } from '@mana/shared-ai';
/** Lifecycle of a Mission. */
export type MissionState = 'active' | 'paused' | 'done' | 'archived';
/** How often the Runner should pick this Mission up. */
export type MissionCadence =
| { readonly kind: 'manual' }
| { readonly kind: 'interval'; readonly everyMinutes: number }
| { readonly kind: 'daily'; readonly atHour: number; readonly atMinute: number }
| {
readonly kind: 'weekly';
readonly dayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;
readonly atHour: number;
}
| { readonly kind: 'cron'; readonly expression: string };
/** Reference to a record in another module this Mission draws context from. */
export interface MissionInputRef {
/** Source module — e.g. `'notes'`, `'goals'`, `'kontext'`. */
readonly module: string;
/** Dexie table name (needed because some modules have multiple). */
readonly table: string;
/** Record id. */
readonly id: string;
}
/** A single step the Planner proposed for the current iteration. */
export interface PlanStep {
readonly id: string;
/** Human-readable summary shown in the Workbench. */
readonly summary: string;
/** What runs — today only toolCalls; later: sub-missions, text-generation, etc. */
readonly intent:
| {
readonly kind: 'toolCall';
readonly toolName: string;
readonly params: Record<string, unknown>;
}
| { readonly kind: 'note'; readonly body: string };
/** Proposal id if this step was staged; undefined before execution. */
readonly proposalId?: string;
/** Outcome of this step. */
readonly status: 'planned' | 'staged' | 'approved' | 'rejected' | 'skipped' | 'failed';
}
/** One autonomous run of the Mission, produced by the Runner invoking the Planner. */
export interface MissionIteration {
readonly id: string;
readonly startedAt: string;
readonly finishedAt?: string;
/** Plan the Planner generated this run. */
readonly plan: readonly PlanStep[];
/** AI's own notes on what it did and why (for the next iteration's context). */
readonly summary?: string;
/** Free-text feedback the user attached on review. */
readonly userFeedback?: string;
/** Shortcut derived from step proposal statuses — used by queries / UI. */
readonly overallStatus: 'running' | 'awaiting-review' | 'approved' | 'rejected' | 'failed';
}
export interface Mission {
readonly id: string;
readonly createdAt: string;
readonly updatedAt: string;
/** Short user-facing name. */
title: string;
/** Markdown doc describing the concept / rules of engagement. */
conceptMarkdown: string;
/** One-sentence concrete objective. */
objective: string;
/** Module records this Mission reads from for context. */
inputs: readonly MissionInputRef[];
/** Cadence the Runner honours. */
cadence: MissionCadence;
/** Lifecycle. */
state: MissionState;
/** ISO timestamp of the next scheduled run, or undefined if not scheduled. */
nextRunAt?: string;
/** All past iterations, newest last. */
iterations: readonly MissionIteration[];
// ── Bookkeeping ──────────────────────────
userId?: string;
deletedAt?: string;
}
export type {
Mission,
MissionCadence,
MissionInputRef,
MissionIteration,
MissionState,
PlanStep,
} from '@mana/shared-ai';
export const MISSIONS_TABLE = 'aiMissions';

View file

@ -0,0 +1,23 @@
{
"name": "@mana/shared-ai",
"version": "0.1.0",
"private": true,
"type": "module",
"sideEffects": false,
"description": "Shared AI Workbench code: actor types, planner prompt + parser, mission types",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts",
"./planner": "./src/planner/index.ts",
"./missions": "./src/missions/index.ts"
},
"scripts": {
"type-check": "tsc --noEmit",
"test": "vitest run"
},
"devDependencies": {
"typescript": "^5.9.3",
"vitest": "^4.1.3"
}
}

View file

@ -0,0 +1,32 @@
/**
* Actor attribution type the discriminated union stamped on every
* event, record, and sync-change row in the Mana system.
*
* Runtime helpers (runAs, runAsAsync, ambient context) stay in the webapp
* because they rely on browser single-threaded semantics and module-level
* mutable state. The *type* is shared so server-side consumers can parse
* incoming actors without re-declaring the union.
*/
export type Actor =
| { readonly kind: 'user' }
| {
readonly kind: 'ai';
readonly missionId: string;
readonly iterationId: string;
readonly rationale: string;
}
| {
readonly kind: 'system';
readonly source: 'projection' | 'rule' | 'migration';
};
export const USER_ACTOR: Actor = Object.freeze({ kind: 'user' });
export function isAiActor(actor: Actor | undefined): boolean {
return actor?.kind === 'ai';
}
export function isSystemActor(actor: Actor | undefined): boolean {
return actor?.kind === 'system';
}

View file

@ -0,0 +1,31 @@
/**
* @mana/shared-ai
*
* AI Workbench code that both the webapp (SvelteKit/Vite) and the
* server-side mana-ai service (Bun) import. Keep this package free of
* runtime imports from storage layers (Dexie, Postgres) the types +
* pure functions here must work in both environments.
*/
export type { Actor } from './actor';
export { USER_ACTOR, isAiActor, isSystemActor } from './actor';
export type {
Mission,
MissionCadence,
MissionInputRef,
MissionIteration,
MissionState,
PlanStep,
} from './missions';
export type {
AiPlanInput,
AiPlanOutput,
AvailableTool,
ParseResult,
PlannedStep,
PlannerMessages,
ResolvedInput,
} from './planner';
export { buildPlannerPrompt, parsePlannerResponse } from './planner';

View file

@ -0,0 +1,8 @@
export type {
Mission,
MissionCadence,
MissionInputRef,
MissionIteration,
MissionState,
PlanStep,
} from './types';

View file

@ -0,0 +1,78 @@
/**
* AI Workbench Mission types the stable contract shared between the
* webapp Runner and the server-side mana-ai service.
*
* Mirrors `apps/mana/apps/web/src/lib/data/ai/missions/types.ts` for the
* runtime shape; the webapp's file re-exports these and adds storage
* concerns (Dexie table name, encryption helpers). Don't diverge without
* a migration both runtimes deserialize the same rows.
*/
export type MissionState = 'active' | 'paused' | 'done' | 'archived';
export type MissionCadence =
| { readonly kind: 'manual' }
| { readonly kind: 'interval'; readonly everyMinutes: number }
| { readonly kind: 'daily'; readonly atHour: number; readonly atMinute: number }
| {
readonly kind: 'weekly';
readonly dayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;
readonly atHour: number;
}
| { readonly kind: 'cron'; readonly expression: string };
export interface MissionInputRef {
readonly module: string;
readonly table: string;
readonly id: string;
}
export interface PlanStep {
readonly id: string;
readonly summary: string;
readonly intent:
| {
readonly kind: 'toolCall';
readonly toolName: string;
readonly params: Record<string, unknown>;
}
| { readonly kind: 'note'; readonly body: string };
readonly proposalId?: string;
readonly status: 'planned' | 'staged' | 'approved' | 'rejected' | 'skipped' | 'failed';
}
export interface MissionIteration {
readonly id: string;
readonly startedAt: string;
readonly finishedAt?: string;
readonly plan: readonly PlanStep[];
readonly summary?: string;
readonly userFeedback?: string;
readonly overallStatus: 'running' | 'awaiting-review' | 'approved' | 'rejected' | 'failed';
/**
* Where this iteration was produced.
* 'browser' the foreground Runner in the user's tab (default).
* 'server' produced by the mana-ai background service;
* on sync, the webapp translates PlanStep[] into local
* Proposals via its staging effect.
* Missing/undefined is treated as 'browser' for back-compat with
* pre-server iterations.
*/
readonly source?: 'browser' | 'server';
}
export interface Mission {
readonly id: string;
readonly createdAt: string;
readonly updatedAt: string;
title: string;
conceptMarkdown: string;
objective: string;
inputs: readonly MissionInputRef[];
cadence: MissionCadence;
state: MissionState;
nextRunAt?: string;
iterations: readonly MissionIteration[];
userId?: string;
deletedAt?: string;
}

View file

@ -0,0 +1,5 @@
export { buildPlannerPrompt } from './prompt';
export type { PlannerMessages } from './prompt';
export { parsePlannerResponse } from './parser';
export type { ParseResult } from './parser';
export type { AiPlanInput, AiPlanOutput, AvailableTool, PlannedStep, ResolvedInput } from './types';

View file

@ -0,0 +1,60 @@
import { describe, it, expect } from 'vitest';
import { parsePlannerResponse } from './parser';
import { buildPlannerPrompt } from './prompt';
import type { AiPlanInput } from './types';
import type { Mission } from '../missions/types';
const TOOLS = new Set(['create_task']);
function mission(): Mission {
return {
id: 'm',
createdAt: '2026-04-14T00:00:00Z',
updatedAt: '2026-04-14T00:00:00Z',
title: 'Test',
conceptMarkdown: '',
objective: 'x',
inputs: [],
cadence: { kind: 'manual' },
state: 'active',
iterations: [],
};
}
describe('shared-ai planner', () => {
it('prompt + parser round-trip a valid plan', () => {
const input: AiPlanInput = {
mission: mission(),
resolvedInputs: [],
availableTools: [
{
name: 'create_task',
module: 'todo',
description: 'Creates a task',
parameters: [{ name: 'title', type: 'string', required: true, description: 'Title' }],
},
],
};
const { system } = buildPlannerPrompt(input);
expect(system).toContain('create_task');
const response = `\`\`\`json
{
"summary": "test",
"steps": [
{ "summary": "s", "toolName": "create_task", "params": { "title": "x" }, "rationale": "why" }
]
}
\`\`\``;
const r = parsePlannerResponse(response, TOOLS);
expect(r.ok).toBe(true);
});
it('rejects unknown tool names', () => {
const r = parsePlannerResponse(
`{"summary":"","steps":[{"toolName":"delete_everything","params":{},"rationale":"lol"}]}`,
TOOLS
);
expect(r.ok).toBe(false);
});
});

View file

@ -0,0 +1,96 @@
/**
* Parser for Planner LLM output.
*
* Strict: we only accept the fenced `json` block the system prompt
* prescribes, validate shape, and surface errors so the Runner can
* record them on the iteration instead of silently producing a bad plan.
*/
import type { AiPlanOutput, PlannedStep } from './types';
export type ParseResult =
| { readonly ok: true; readonly value: AiPlanOutput }
| { readonly ok: false; readonly reason: string; readonly raw?: string };
export function parsePlannerResponse(text: string, knownToolNames: Set<string>): ParseResult {
const block = extractJsonBlock(text);
if (!block) return { ok: false, reason: 'no JSON block found', raw: text };
let parsed: unknown;
try {
parsed = JSON.parse(block);
} catch (err) {
return {
ok: false,
reason: `JSON parse failed: ${err instanceof Error ? err.message : String(err)}`,
raw: block,
};
}
if (typeof parsed !== 'object' || parsed === null) {
return { ok: false, reason: 'top-level value is not an object', raw: block };
}
const obj = parsed as Record<string, unknown>;
const summary = typeof obj.summary === 'string' ? obj.summary : '';
const rawSteps = obj.steps;
if (!Array.isArray(rawSteps)) {
return { ok: false, reason: '`steps` must be an array', raw: block };
}
const steps: PlannedStep[] = [];
for (let i = 0; i < rawSteps.length; i++) {
const step = rawSteps[i];
const validation = validateStep(step, knownToolNames, i);
if (!validation.ok) {
return { ok: false, reason: validation.reason, raw: block };
}
steps.push(validation.value);
}
return { ok: true, value: { summary, steps } };
}
function extractJsonBlock(text: string): string | null {
const fenced = /```(?:json)?\s*\n?([\s\S]*?)\n?```/;
const m = text.match(fenced);
if (m) return m[1].trim();
const trimmed = text.trim();
if (trimmed.startsWith('{') && trimmed.endsWith('}')) return trimmed;
return null;
}
function validateStep(
raw: unknown,
knownToolNames: Set<string>,
index: number
): { ok: true; value: PlannedStep } | { ok: false; reason: string } {
if (typeof raw !== 'object' || raw === null) {
return { ok: false, reason: `step[${index}] is not an object` };
}
const obj = raw as Record<string, unknown>;
const toolName = obj.toolName;
if (typeof toolName !== 'string' || toolName.length === 0) {
return { ok: false, reason: `step[${index}].toolName missing or not a string` };
}
if (!knownToolNames.has(toolName)) {
return {
ok: false,
reason: `step[${index}].toolName "${toolName}" is not in the allowed tool set`,
};
}
const summary = typeof obj.summary === 'string' ? obj.summary : '';
const rationale = typeof obj.rationale === 'string' ? obj.rationale : '';
if (rationale.length === 0) {
return { ok: false, reason: `step[${index}].rationale is required (user will see this)` };
}
const params =
typeof obj.params === 'object' && obj.params !== null
? (obj.params as Record<string, unknown>)
: {};
return {
ok: true,
value: { summary, toolName, rationale, params },
};
}

View file

@ -0,0 +1,112 @@
/**
* Prompt builder for the Mission Planner.
*
* Produces a system + user message pair. The grammar we ask the model to
* return is deliberately small (JSON in a fenced block, one shape) the
* parser is strict, and we'd rather the LLM mess up in a detectable way
* than produce half-valid output.
*
* Pure function: no ambient state. Used identically from the browser and
* the mana-ai Bun service.
*/
import type { AiPlanInput } from './types';
export interface PlannerMessages {
readonly system: string;
readonly user: string;
}
export function buildPlannerPrompt(input: AiPlanInput): PlannerMessages {
return {
system: buildSystemPrompt(input),
user: buildUserPrompt(input),
};
}
function buildSystemPrompt(input: AiPlanInput): string {
const toolBlock = input.availableTools
.map((t) => {
const params = t.parameters
.map((p) => {
const req = p.required ? ' (required)' : '';
const enumeration = p.enum ? ` [${p.enum.join('|')}]` : '';
return ` - ${p.name}: ${p.type}${enumeration}${req}${p.description}`;
})
.join('\n');
return `${t.name} (${t.module}) — ${t.description}\n${params || ' (no parameters)'}`;
})
.join('\n');
return `Du bist eine KI, die im Auftrag des Nutzers an einer langlebigen Mission arbeitet.
Dein Job: aus dem aktuellen Mission-Kontext einen kurzen, konkreten Plan ableiten 1 bis 5 Schritte, jeder ein Tool-Aufruf auf Nutzerdaten. Jeder Schritt MUSS eine Begründung haben (rationale), die der Nutzer in der Review-UI sieht.
Wichtige Regeln:
1. Nutze NUR Tools aus der Liste unten. Unbekannte Tools Plan invalide.
2. Jeder Step wird als Proposal gestaged der Nutzer approved oder rejected. Du schreibst nie direkt.
3. Berücksichtige das Feedback aus vorherigen Iterationen (unten im User-Prompt). Wenn ein Vorschlag rejected wurde, wiederhole ihn nicht ohne Änderung.
4. Antworte AUSSCHLIESSLICH mit einem JSON-Block in folgendem Format, keine Prosa davor/danach:
\`\`\`json
{
"summary": "Ein Satz was du in dieser Iteration tust.",
"steps": [
{
"summary": "Kurzer Schritt-Titel",
"toolName": "create_task",
"params": { "title": "…" },
"rationale": "Warum genau jetzt, auf Basis welchen Inputs."
}
]
}
\`\`\`
Verfügbare Tools:
${toolBlock || ' (keine Tools verfügbar — gib leeren steps zurück)'}`;
}
function buildUserPrompt(input: AiPlanInput): string {
const { mission, resolvedInputs } = input;
const inputsBlock =
resolvedInputs.length === 0
? '_(keine verlinkten Inputs)_'
: resolvedInputs
.map((r) => {
const header = `### ${r.module}/${r.table}: ${r.title ?? r.id}`;
return `${header}\n${r.content}`;
})
.join('\n\n');
const iterationHistory =
mission.iterations.length === 0
? '_(erste Iteration)_'
: mission.iterations
.slice(-3)
.map((it) => {
const steps = it.plan.map((s) => ` - [${s.status}] ${s.summary}`).join('\n');
const feedback = it.userFeedback ? `\n Nutzer-Feedback: ${it.userFeedback}` : '';
const summary = it.summary ? `\n Summary: ${it.summary}` : '';
return `**${it.startedAt}** (${it.overallStatus}):${summary}\n${steps}${feedback}`;
})
.join('\n\n');
return `# Mission: ${mission.title}
## Konzept
${mission.conceptMarkdown || '_(leer)_'}
## Konkretes Ziel
${mission.objective}
## Verlinkte Inputs
${inputsBlock}
## Letzte Iterationen (max. 3)
${iterationHistory}
---
Erzeuge jetzt einen Plan für die nächste Iteration.`;
}

View file

@ -0,0 +1,45 @@
/**
* Planner contract input/output shape consumed by the prompt builder
* and parser. Identical between browser and server runtimes.
*/
import type { Mission } from '../missions/types';
export interface ResolvedInput {
readonly id: string;
readonly module: string;
readonly table: string;
readonly title?: string;
readonly content: string;
}
export interface AvailableTool {
readonly name: string;
readonly module: string;
readonly description: string;
readonly parameters: ReadonlyArray<{
readonly name: string;
readonly type: string;
readonly required: boolean;
readonly description: string;
readonly enum?: readonly string[];
}>;
}
export interface AiPlanInput {
readonly mission: Mission;
readonly resolvedInputs: readonly ResolvedInput[];
readonly availableTools: readonly AvailableTool[];
}
export interface PlannedStep {
readonly summary: string;
readonly toolName: string;
readonly params: Record<string, unknown>;
readonly rationale: string;
}
export interface AiPlanOutput {
readonly steps: readonly PlannedStep[];
readonly summary: string;
}

View file

@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"noEmit": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}

564
pnpm-lock.yaml generated
View file

@ -138,14 +138,14 @@ importers:
version: link:../../../../packages/shared-landing-ui
astro:
specifier: ^5.16.0
version: 5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@1.21.7)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)
version: 5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)
typescript:
specifier: ^5.9.2
version: 5.9.3
devDependencies:
'@astrojs/tailwind':
specifier: ^6.0.2
version: 6.0.2(astro@5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@1.21.7)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))
version: 6.0.2(astro@5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))
'@tailwindcss/typography':
specifier: ^0.5.18
version: 0.5.19(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))
@ -154,13 +154,13 @@ importers:
version: 20.19.39
eslint:
specifier: ^9.0.0
version: 9.39.4(jiti@1.21.7)
version: 9.39.4(jiti@2.6.1)
eslint-config-prettier:
specifier: ^9.1.0
version: 9.1.2(eslint@9.39.4(jiti@1.21.7))
version: 9.1.2(eslint@9.39.4(jiti@2.6.1))
eslint-plugin-astro:
specifier: ^1.0.0
version: 1.6.0(eslint@9.39.4(jiti@1.21.7))
version: 1.6.0(eslint@9.39.4(jiti@2.6.1))
prettier:
specifier: ^3.6.2
version: 3.8.1
@ -484,19 +484,19 @@ importers:
version: 19.1.17
'@typescript-eslint/eslint-plugin':
specifier: ^7.7.0
version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/parser':
specifier: ^7.7.0
version: 7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
version: 7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
dotenv:
specifier: ^16.4.7
version: 16.6.1
eslint:
specifier: ^9.39.1
version: 9.39.4(jiti@2.6.1)
version: 9.39.4(jiti@1.21.7)
eslint-config-universe:
specifier: ^12.0.1
version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.4(jiti@2.6.1))(prettier@3.8.1)(typescript@5.3.3)
version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.4(jiti@1.21.7))(prettier@3.8.1)(typescript@5.3.3)
prettier:
specifier: ^3.2.5
version: 3.8.1
@ -1027,6 +1027,9 @@ importers:
'@mana/qr-export':
specifier: workspace:*
version: link:../../../../packages/qr-export
'@mana/shared-ai':
specifier: workspace:*
version: link:../../../../packages/shared-ai
'@mana/shared-auth':
specifier: workspace:*
version: link:../../../../packages/shared-auth
@ -2756,6 +2759,15 @@ importers:
specifier: ^4.1.2
version: 4.1.3(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.3)(@vitest/ui@4.1.3)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
packages/shared-ai:
devDependencies:
typescript:
specifier: ^5.9.3
version: 5.9.3
vitest:
specifier: ^4.1.3
version: 4.1.3(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.3)(@vitest/ui@4.1.3)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
packages/shared-auth:
dependencies:
'@mana/shared-types':
@ -3271,6 +3283,25 @@ importers:
specifier: ^4.1.2
version: 4.1.3(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.3)(@vitest/ui@4.1.3)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
services/mana-ai:
dependencies:
'@mana/shared-hono':
specifier: workspace:*
version: link:../../packages/shared-hono
hono:
specifier: ^4.7.0
version: 4.12.12
postgres:
specifier: ^3.4.5
version: 3.4.9
devDependencies:
'@types/bun':
specifier: latest
version: 1.3.12
typescript:
specifier: ^5.9.3
version: 5.9.3
services/mana-analytics:
dependencies:
'@mana/shared-hono':
@ -17995,16 +18026,6 @@ snapshots:
transitivePeerDependencies:
- ts-node
'@astrojs/tailwind@6.0.2(astro@5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@1.21.7)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))':
dependencies:
astro: 5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@1.21.7)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)
autoprefixer: 10.4.27(postcss@8.5.8)
postcss: 8.5.8
postcss-load-config: 4.0.2(postcss@8.5.8)
tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3)
transitivePeerDependencies:
- ts-node
'@astrojs/tailwind@6.0.2(astro@5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))':
dependencies:
astro: 5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)
@ -20353,82 +20374,6 @@ snapshots:
- supports-color
- utf-8-validate
'@expo/cli@55.0.22(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0))(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)':
dependencies:
'@expo/code-signing-certificates': 0.0.6
'@expo/config': 55.0.13(typescript@5.9.3)
'@expo/config-plugins': 55.0.8
'@expo/devcert': 1.2.1
'@expo/env': 2.1.1
'@expo/image-utils': 0.8.12
'@expo/json-file': 10.0.13
'@expo/log-box': 55.0.10(@expo/dom-webview@55.0.5)(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)
'@expo/metro': 55.0.0
'@expo/metro-config': 55.0.14(expo@55.0.12)(typescript@5.9.3)
'@expo/osascript': 2.4.2
'@expo/package-manager': 1.10.4
'@expo/plist': 0.5.2
'@expo/prebuild-config': 55.0.13(expo@55.0.12)(typescript@5.9.3)
'@expo/require-utils': 55.0.3(typescript@5.9.3)
'@expo/router-server': 55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0))(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
'@expo/schema-utils': 55.0.3
'@expo/spawn-async': 1.7.2
'@expo/ws-tunnel': 1.0.6
'@expo/xcpretty': 4.4.1
'@react-native/dev-middleware': 0.83.4
accepts: 1.3.8
arg: 5.0.2
better-opn: 3.0.2
bplist-creator: 0.1.0
bplist-parser: 0.3.2
chalk: 4.1.2
ci-info: 3.9.0
compression: 1.8.1
connect: 3.7.0
debug: 4.4.3
dnssd-advertise: 1.1.4
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo-server: 55.0.7
fetch-nodeshim: 0.4.10
getenv: 2.0.0
glob: 13.0.6
lan-network: 0.2.1
multitars: 0.2.4
node-forge: 1.4.0
npm-package-arg: 11.0.3
ora: 3.4.0
picomatch: 4.0.4
pretty-format: 29.7.0
progress: 2.0.3
prompts: 2.4.2
resolve-from: 5.0.0
semver: 7.7.4
send: 0.19.2
slugify: 1.6.9
source-map-support: 0.5.21
stacktrace-parser: 0.1.11
structured-headers: 0.4.1
terminal-link: 2.1.1
toqr: 0.1.1
wrap-ansi: 7.0.0
ws: 8.20.0
zod: 3.25.76
optionalDependencies:
expo-router: 55.0.11(pdj77jcnw7u2taeri5ruj5t4mi)
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
transitivePeerDependencies:
- '@expo/dom-webview'
- '@expo/metro-runtime'
- bufferutil
- expo-constants
- expo-font
- react
- react-dom
- react-server-dom-webpack
- supports-color
- typescript
- utf-8-validate
'@expo/cli@55.0.22(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)':
dependencies:
'@expo/code-signing-certificates': 0.0.6
@ -20581,6 +20526,82 @@ snapshots:
- typescript
- utf-8-validate
'@expo/cli@55.0.22(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)':
dependencies:
'@expo/code-signing-certificates': 0.0.6
'@expo/config': 55.0.13(typescript@5.9.3)
'@expo/config-plugins': 55.0.8
'@expo/devcert': 1.2.1
'@expo/env': 2.1.1
'@expo/image-utils': 0.8.12
'@expo/json-file': 10.0.13
'@expo/log-box': 55.0.10(@expo/dom-webview@55.0.5)(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)
'@expo/metro': 55.0.0
'@expo/metro-config': 55.0.14(expo@55.0.12)(typescript@5.9.3)
'@expo/osascript': 2.4.2
'@expo/package-manager': 1.10.4
'@expo/plist': 0.5.2
'@expo/prebuild-config': 55.0.13(expo@55.0.12)(typescript@5.9.3)
'@expo/require-utils': 55.0.3(typescript@5.9.3)
'@expo/router-server': 55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
'@expo/schema-utils': 55.0.3
'@expo/spawn-async': 1.7.2
'@expo/ws-tunnel': 1.0.6
'@expo/xcpretty': 4.4.1
'@react-native/dev-middleware': 0.83.4
accepts: 1.3.8
arg: 5.0.2
better-opn: 3.0.2
bplist-creator: 0.1.0
bplist-parser: 0.3.2
chalk: 4.1.2
ci-info: 3.9.0
compression: 1.8.1
connect: 3.7.0
debug: 4.4.3
dnssd-advertise: 1.1.4
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo-server: 55.0.7
fetch-nodeshim: 0.4.10
getenv: 2.0.0
glob: 13.0.6
lan-network: 0.2.1
multitars: 0.2.4
node-forge: 1.4.0
npm-package-arg: 11.0.3
ora: 3.4.0
picomatch: 4.0.4
pretty-format: 29.7.0
progress: 2.0.3
prompts: 2.4.2
resolve-from: 5.0.0
semver: 7.7.4
send: 0.19.2
slugify: 1.6.9
source-map-support: 0.5.21
stacktrace-parser: 0.1.11
structured-headers: 0.4.1
terminal-link: 2.1.1
toqr: 0.1.1
wrap-ansi: 7.0.0
ws: 8.20.0
zod: 3.25.76
optionalDependencies:
expo-router: 55.0.11(eq6waxwbjtmotercssqwfwfcim)
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
transitivePeerDependencies:
- '@expo/dom-webview'
- '@expo/metro-runtime'
- bufferutil
- expo-constants
- expo-font
- react
- react-dom
- react-server-dom-webpack
- supports-color
- typescript
- utf-8-validate
'@expo/cli@55.0.22(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)':
dependencies:
'@expo/code-signing-certificates': 0.0.6
@ -20808,7 +20829,7 @@ snapshots:
'@expo/dom-webview@55.0.5(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)':
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react: 19.2.0
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
@ -20921,7 +20942,7 @@ snapshots:
dependencies:
'@expo/dom-webview': 55.0.5(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)
anser: 1.4.10
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react: 19.2.0
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
stacktrace-parser: 0.1.11
@ -21045,7 +21066,7 @@ snapshots:
postcss: 8.4.49
resolve-from: 5.0.0
optionalDependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
transitivePeerDependencies:
- bufferutil
- supports-color
@ -21072,7 +21093,7 @@ snapshots:
dependencies:
'@expo/log-box': 55.0.10(@expo/dom-webview@55.0.5)(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)
anser: 1.4.10
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
pretty-format: 29.7.0
react: 19.2.0
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
@ -21224,7 +21245,7 @@ snapshots:
'@expo/json-file': 10.0.13
'@react-native/normalize-colors': 0.83.4
debug: 4.4.3
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
resolve-from: 5.0.0
semver: 7.7.4
xml2js: 0.6.0
@ -21270,21 +21291,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@expo/router-server@55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0))(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
dependencies:
debug: 4.4.3
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(typescript@5.9.3)
expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)
expo-server: 55.0.7
react: 19.2.0
optionalDependencies:
'@expo/metro-runtime': 55.0.9(@expo/dom-webview@55.0.5)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)
expo-router: 55.0.11(pdj77jcnw7u2taeri5ruj5t4mi)
react-dom: 19.2.0(react@19.2.0)
transitivePeerDependencies:
- supports-color
'@expo/router-server@55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
dependencies:
debug: 4.4.3
@ -25119,16 +25125,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/type-utils': 6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/type-utils': 6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.4.3
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
@ -25177,15 +25183,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/parser': 7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/type-utils': 7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/type-utils': 7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.18.0
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
@ -25258,14 +25264,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/types': 6.21.0
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.4.3
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
optionalDependencies:
typescript: 5.3.3
transitivePeerDependencies:
@ -25297,14 +25303,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.4.3
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
optionalDependencies:
typescript: 5.3.3
transitivePeerDependencies:
@ -25400,12 +25406,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/type-utils@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/type-utils@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
debug: 4.4.3
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
ts-api-utils: 1.4.3(typescript@5.3.3)
optionalDependencies:
typescript: 5.3.3
@ -25436,12 +25442,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/type-utils@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/type-utils@7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
debug: 4.4.3
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
ts-api-utils: 1.4.3(typescript@5.3.3)
optionalDependencies:
typescript: 5.3.3
@ -25594,15 +25600,15 @@ snapshots:
- supports-color
- typescript
'@typescript-eslint/utils@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/utils@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1))
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7))
'@types/json-schema': 7.0.15
'@types/semver': 7.7.1
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/types': 6.21.0
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
semver: 7.7.4
transitivePeerDependencies:
- supports-color
@ -25633,13 +25639,13 @@ snapshots:
- supports-color
- typescript
'@typescript-eslint/utils@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)':
'@typescript-eslint/utils@7.18.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1))
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7))
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
transitivePeerDependencies:
- supports-color
- typescript
@ -25830,7 +25836,7 @@ snapshots:
obug: 2.1.1
std-env: 4.0.0
tinyrainbow: 3.1.0
vitest: 4.1.3(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.3)(@vitest/ui@4.1.3)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
vitest: 4.1.3(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(@vitest/coverage-v8@4.1.3)(@vitest/ui@4.1.3)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@6.4.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
'@vitest/expect@4.1.3':
dependencies:
@ -25892,7 +25898,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.1.0
vitest: 4.1.3(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.3)(@vitest/ui@4.1.3)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
vitest: 4.1.3(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(@vitest/coverage-v8@4.1.3)(@vitest/ui@4.1.3)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@6.4.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
'@vitest/utils@4.1.3':
dependencies:
@ -26323,108 +26329,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
astro@5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@1.21.7)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3):
dependencies:
'@astrojs/compiler': 2.13.1
'@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(rollup@4.60.1)
acorn: 8.16.0
aria-query: 5.3.2
axobject-query: 4.1.0
boxen: 8.0.1
ci-info: 4.4.0
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.7.0
diff: 8.0.4
dlv: 1.1.3
dset: 3.1.4
es-module-lexer: 1.7.0
esbuild: 0.27.7
estree-walker: 3.0.3
flattie: 1.1.1
fontace: 0.4.1
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.2
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.4
prompts: 2.4.2
rehype: 13.0.2
semver: 7.7.4
shiki: 3.23.0
smol-toml: 1.6.1
svgo: 4.0.1
tinyexec: 1.0.4
tinyglobby: 0.2.15
tsconfck: 3.1.6(typescript@5.9.3)
ultrahtml: 1.6.0
unifont: 0.7.4
unist-util-visit: 5.1.0
unstorage: 1.17.5(@azure/storage-blob@12.31.0)(ioredis@5.10.1)
vfile: 6.0.3
vite: 6.4.2(@types/node@20.19.39)(jiti@1.21.7)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
vitefu: 1.1.3(vite@6.4.2(@types/node@20.19.39)(jiti@1.21.7)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
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.2(zod@3.25.76)
zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76)
optionalDependencies:
sharp: 0.34.5
transitivePeerDependencies:
- '@azure/app-configuration'
- '@azure/cosmos'
- '@azure/data-tables'
- '@azure/identity'
- '@azure/keyvault-secrets'
- '@azure/storage-blob'
- '@capacitor/preferences'
- '@deno/kv'
- '@netlify/blobs'
- '@planetscale/database'
- '@types/node'
- '@upstash/redis'
- '@vercel/blob'
- '@vercel/functions'
- '@vercel/kv'
- aws4fetch
- db0
- idb-keyval
- ioredis
- jiti
- less
- lightningcss
- rollup
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- typescript
- uploadthing
- yaml
astro@5.18.1(@azure/storage-blob@12.31.0)(@types/node@20.19.39)(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.1)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3):
dependencies:
'@astrojs/compiler': 2.13.1
@ -26938,7 +26842,7 @@ snapshots:
resolve-from: 5.0.0
optionalDependencies:
'@babel/runtime': 7.29.2
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
transitivePeerDependencies:
- '@babel/core'
- supports-color
@ -28440,11 +28344,6 @@ snapshots:
eslint: 9.39.4(jiti@2.6.1)
semver: 7.7.4
eslint-compat-utils@0.6.5(eslint@9.39.4(jiti@1.21.7)):
dependencies:
eslint: 9.39.4(jiti@1.21.7)
semver: 7.7.4
eslint-compat-utils@0.6.5(eslint@9.39.4(jiti@2.6.1)):
dependencies:
eslint: 9.39.4(jiti@2.6.1)
@ -28492,14 +28391,14 @@ snapshots:
dependencies:
eslint: 8.57.1
eslint-config-prettier@8.10.2(eslint@9.39.4(jiti@1.21.7)):
dependencies:
eslint: 9.39.4(jiti@1.21.7)
eslint-config-prettier@8.10.2(eslint@9.39.4(jiti@2.6.1)):
dependencies:
eslint: 9.39.4(jiti@2.6.1)
eslint-config-prettier@9.1.2(eslint@9.39.4(jiti@1.21.7)):
dependencies:
eslint: 9.39.4(jiti@1.21.7)
eslint-config-prettier@9.1.2(eslint@9.39.4(jiti@2.6.1)):
dependencies:
eslint: 9.39.4(jiti@2.6.1)
@ -28524,17 +28423,17 @@ snapshots:
- supports-color
- typescript
eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.4(jiti@2.6.1))(prettier@3.8.1)(typescript@5.3.3):
eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.4(jiti@1.21.7))(prettier@3.8.1)(typescript@5.3.3):
dependencies:
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
eslint: 9.39.4(jiti@2.6.1)
eslint-config-prettier: 8.10.2(eslint@9.39.4(jiti@2.6.1))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.4(jiti@2.6.1))
eslint-plugin-node: 11.1.0(eslint@9.39.4(jiti@2.6.1))
eslint-plugin-prettier: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(prettier@3.8.1)
eslint-plugin-react: 7.37.5(eslint@9.39.4(jiti@2.6.1))
eslint-plugin-react-hooks: 4.6.2(eslint@9.39.4(jiti@2.6.1))
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
eslint: 9.39.4(jiti@1.21.7)
eslint-config-prettier: 8.10.2(eslint@9.39.4(jiti@1.21.7))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.4(jiti@1.21.7))
eslint-plugin-node: 11.1.0(eslint@9.39.4(jiti@1.21.7))
eslint-plugin-prettier: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.4(jiti@1.21.7)))(eslint@9.39.4(jiti@1.21.7))(prettier@3.8.1)
eslint-plugin-react: 7.37.5(eslint@9.39.4(jiti@1.21.7))
eslint-plugin-react-hooks: 4.6.2(eslint@9.39.4(jiti@1.21.7))
optionalDependencies:
prettier: 3.8.1
transitivePeerDependencies:
@ -28641,12 +28540,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.4(jiti@2.6.1)):
eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.4(jiti@1.21.7)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
eslint: 9.39.4(jiti@2.6.1)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
eslint: 9.39.4(jiti@1.21.7)
eslint-import-resolver-node: 0.3.10
transitivePeerDependencies:
- supports-color
@ -28683,20 +28582,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-astro@1.6.0(eslint@9.39.4(jiti@1.21.7)):
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7))
'@jridgewell/sourcemap-codec': 1.5.5
'@typescript-eslint/types': 8.58.0
astro-eslint-parser: 1.4.0
eslint: 9.39.4(jiti@1.21.7)
eslint-compat-utils: 0.6.5(eslint@9.39.4(jiti@1.21.7))
globals: 16.5.0
postcss: 8.5.8
postcss-selector-parser: 7.1.1
transitivePeerDependencies:
- supports-color
eslint-plugin-astro@1.6.0(eslint@9.39.4(jiti@2.6.1)):
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1))
@ -28724,6 +28609,12 @@ snapshots:
eslint-utils: 2.1.0
regexpp: 3.2.0
eslint-plugin-es@3.0.1(eslint@9.39.4(jiti@1.21.7)):
dependencies:
eslint: 9.39.4(jiti@1.21.7)
eslint-utils: 2.1.0
regexpp: 3.2.0
eslint-plugin-es@3.0.1(eslint@9.39.4(jiti@2.6.1)):
dependencies:
eslint: 9.39.4(jiti@2.6.1)
@ -28777,7 +28668,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.4(jiti@2.6.1)):
eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.4(jiti@1.21.7)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@ -28786,9 +28677,9 @@ snapshots:
array.prototype.flatmap: 1.3.3
debug: 3.2.7
doctrine: 2.1.0
eslint: 9.39.4(jiti@2.6.1)
eslint: 9.39.4(jiti@1.21.7)
eslint-import-resolver-node: 0.3.10
eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.4(jiti@2.6.1))
eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.4(jiti@1.21.7))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@ -28800,7 +28691,7 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.4(jiti@1.21.7))(typescript@5.3.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@ -28918,6 +28809,16 @@ snapshots:
resolve: 1.22.11
semver: 6.3.1
eslint-plugin-node@11.1.0(eslint@9.39.4(jiti@1.21.7)):
dependencies:
eslint: 9.39.4(jiti@1.21.7)
eslint-plugin-es: 3.0.1(eslint@9.39.4(jiti@1.21.7))
eslint-utils: 2.1.0
ignore: 5.3.2
minimatch: 3.1.5
resolve: 1.22.11
semver: 6.3.1
eslint-plugin-node@11.1.0(eslint@9.39.4(jiti@2.6.1)):
dependencies:
eslint: 9.39.4(jiti@2.6.1)
@ -28948,6 +28849,16 @@ snapshots:
'@types/eslint': 9.6.1
eslint-config-prettier: 8.10.2(eslint@8.57.1)
eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.4(jiti@1.21.7)))(eslint@9.39.4(jiti@1.21.7))(prettier@3.8.1):
dependencies:
eslint: 9.39.4(jiti@1.21.7)
prettier: 3.8.1
prettier-linter-helpers: 1.0.1
synckit: 0.11.12
optionalDependencies:
'@types/eslint': 9.6.1
eslint-config-prettier: 8.10.2(eslint@9.39.4(jiti@1.21.7))
eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(prettier@3.8.1):
dependencies:
eslint: 9.39.4(jiti@2.6.1)
@ -28972,6 +28883,10 @@ snapshots:
dependencies:
eslint: 8.57.1
eslint-plugin-react-hooks@4.6.2(eslint@9.39.4(jiti@1.21.7)):
dependencies:
eslint: 9.39.4(jiti@1.21.7)
eslint-plugin-react-hooks@4.6.2(eslint@9.39.4(jiti@2.6.1)):
dependencies:
eslint: 9.39.4(jiti@2.6.1)
@ -29002,6 +28917,28 @@ snapshots:
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@1.21.7)):
dependencies:
array-includes: 3.1.9
array.prototype.findlast: 1.2.5
array.prototype.flatmap: 1.3.3
array.prototype.tosorted: 1.1.4
doctrine: 2.1.0
es-iterator-helpers: 1.3.1
eslint: 9.39.4(jiti@1.21.7)
estraverse: 5.3.0
hasown: 2.0.2
jsx-ast-utils: 3.3.5
minimatch: 3.1.5
object.entries: 1.1.9
object.fromentries: 2.0.8
object.values: 1.2.1
prop-types: 15.8.1
resolve: 2.0.0-next.6
semver: 6.3.1
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.6.1)):
dependencies:
array-includes: 3.1.9
@ -29505,7 +29442,7 @@ snapshots:
expo-dev-client@6.0.20(expo@55.0.12):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
expo-dev-launcher: 6.0.20(expo@55.0.12)
expo-dev-menu: 7.0.18(expo@55.0.12)
expo-dev-menu-interface: 2.0.0(expo@55.0.12)
@ -29527,7 +29464,7 @@ snapshots:
expo-dev-launcher@6.0.20(expo@55.0.12):
dependencies:
ajv: 8.18.0
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
expo-dev-menu: 7.0.18(expo@55.0.12)
expo-manifests: 1.0.10(expo@55.0.12)
transitivePeerDependencies:
@ -29535,7 +29472,7 @@ snapshots:
expo-dev-menu-interface@2.0.0(expo@55.0.12):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
expo-dev-menu-interface@55.0.2(expo@55.0.12):
dependencies:
@ -29548,7 +29485,7 @@ snapshots:
expo-dev-menu@7.0.18(expo@55.0.12):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
expo-dev-menu-interface: 2.0.0(expo@55.0.12)
expo-device@55.0.13(expo@55.0.12):
@ -29574,7 +29511,7 @@ snapshots:
expo-file-system@55.0.15(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
expo-file-system@55.0.15(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)):
@ -29598,7 +29535,7 @@ snapshots:
expo-font@55.0.6(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
fontfaceobserver: 2.3.0
react: 19.2.0
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
@ -29619,7 +29556,7 @@ snapshots:
expo-glass-effect@55.0.10(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react: 19.2.0
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
@ -29635,11 +29572,11 @@ snapshots:
expo-image-loader@55.0.0(expo@55.0.12):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo-image-picker@55.0.17(expo@55.0.12):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo-image-loader: 55.0.0(expo@55.0.12)
expo-image@55.0.8(expo@54.0.33)(react-native-web@0.21.2(react-dom@19.2.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.1.0))(react@19.1.0):
@ -29654,7 +29591,7 @@ snapshots:
expo-image@55.0.8(expo@55.0.12)(react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react: 19.2.0
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
sf-symbols-typescript: 2.2.0
@ -29681,7 +29618,7 @@ snapshots:
expo-keep-awake@55.0.6(expo@55.0.12)(react@19.2.0):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react: 19.2.0
expo-linear-gradient@15.0.8(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0):
@ -29777,7 +29714,7 @@ snapshots:
expo-manifests@1.0.10(expo@55.0.12):
dependencies:
'@expo/config': 12.0.13
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
expo-json-utils: 0.15.0
transitivePeerDependencies:
- supports-color
@ -30149,7 +30086,7 @@ snapshots:
expo-secure-store@55.0.12(expo@55.0.12):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo-server@1.0.5: {}
@ -30244,7 +30181,7 @@ snapshots:
dependencies:
'@react-native/normalize-colors': 0.83.4
debug: 4.4.3
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
optionalDependencies:
react-native-web: 0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
@ -30270,7 +30207,7 @@ snapshots:
expo-updates-interface@2.0.0(expo@55.0.12):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
expo-updates-interface@55.1.5(expo@55.0.12):
dependencies:
@ -30300,7 +30237,7 @@ snapshots:
expo-web-browser@55.0.13(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)):
dependencies:
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.3.3)
react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0)
expo@54.0.33(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-native@0.81.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.1.0))(react@19.1.0):
@ -30424,7 +30361,7 @@ snapshots:
expo@55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3):
dependencies:
'@babel/runtime': 7.29.2
'@expo/cli': 55.0.22(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6(expo@55.0.12)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0))(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
'@expo/cli': 55.0.22(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
'@expo/config': 55.0.13(typescript@5.9.3)
'@expo/config-plugins': 55.0.8
'@expo/devtools': 55.0.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.2.0))(react@19.2.0)
@ -37216,23 +37153,6 @@ snapshots:
lightningcss: 1.32.0
terser: 5.46.1
vite@6.4.2(@types/node@20.19.39)(jiti@1.21.7)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3):
dependencies:
esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4
postcss: 8.5.8
rollup: 4.60.1
tinyglobby: 0.2.15
optionalDependencies:
'@types/node': 20.19.39
fsevents: 2.3.3
jiti: 1.21.7
lightningcss: 1.32.0
terser: 5.46.1
tsx: 4.21.0
yaml: 2.8.3
vite@6.4.2(@types/node@20.19.39)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3):
dependencies:
esbuild: 0.25.12
@ -37284,10 +37204,6 @@ snapshots:
tsx: 4.21.0
yaml: 2.8.3
vitefu@1.1.3(vite@6.4.2(@types/node@20.19.39)(jiti@1.21.7)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
optionalDependencies:
vite: 6.4.2(@types/node@20.19.39)(jiti@1.21.7)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
vitefu@1.1.3(vite@6.4.2(@types/node@20.19.39)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
optionalDependencies:
vite: 6.4.2(@types/node@20.19.39)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)