mirror of
https://github.com/lukaszraczylo/claude-mnemonic.git
synced 2026-10-12 04:55:18 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67de0f0c84 | ||
|
|
eba3136fff | ||
|
|
17f7bffef5 | ||
|
|
0d75b867e6 | ||
|
|
a8e9d0f256 | ||
|
|
8857cc9c72 | ||
|
|
096490a2d3 | ||
|
|
eaf7c4ddca | ||
|
|
2d1f52cdf4 |
@@ -1,4 +1,4 @@
|
||||
name: Autoupdate go.mod and go.sum
|
||||
name: Update dependencies
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -6,16 +6,16 @@ on:
|
||||
- cron: "0 3 * * *"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
autoupdate:
|
||||
uses: lukaszraczylo/shared-actions/.github/workflows/go-autoupdate.yaml@main
|
||||
update:
|
||||
uses: lukaszraczylo/shared-actions/.github/workflows/renovate-autoupdate.yaml@main
|
||||
with:
|
||||
go-version: ">=1.24"
|
||||
release-workflow: "release.yaml"
|
||||
lfs: false
|
||||
secrets: inherit
|
||||
node-working-directory: ui
|
||||
require-node-tests: false
|
||||
release-workflow: release.yaml
|
||||
|
||||
@@ -139,9 +139,22 @@ func NewClient(cfg Config, embedSvc *embedding.Service) (*Client, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// AddDocuments adds documents with their embeddings to the vector store.
|
||||
// AddDocuments embeds the documents and inserts them. A document whose ID already exists is an error (the vec0
|
||||
// table does not replace on insert); use ReplaceDocuments to write the documents of a note that may have some.
|
||||
func (c *Client) AddDocuments(ctx context.Context, docs []Document) error {
|
||||
if len(docs) == 0 {
|
||||
return c.writeDocuments(ctx, docs, "", 0)
|
||||
}
|
||||
|
||||
// ReplaceDocuments writes the documents of one note (observation, summary, ...) in place of the ones it had: the old
|
||||
// documents are deleted and the new ones inserted in one transaction, so an edit that removes a fact leaves no stale
|
||||
// document behind and a failure leaves the old ones untouched. docs may be empty, which only deletes.
|
||||
func (c *Client) ReplaceDocuments(ctx context.Context, docType string, sqliteID int64, docs []Document) error {
|
||||
return c.writeDocuments(ctx, docs, docType, sqliteID)
|
||||
}
|
||||
|
||||
// writeDocuments inserts docs; when docType is not empty it first deletes every document of that note.
|
||||
func (c *Client) writeDocuments(ctx context.Context, docs []Document, docType string, sqliteID int64) (err error) {
|
||||
if len(docs) == 0 && docType == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -154,9 +167,11 @@ func (c *Client) AddDocuments(ctx context.Context, docs []Document) error {
|
||||
// Compute embeddings OUTSIDE the write lock for better concurrency.
|
||||
// Embedding is ONNX inference (slow, mutex-protected internally) — holding
|
||||
// writeMu during inference blocks all concurrent writes and reads.
|
||||
embeddings, err := c.embedSvc.EmbedBatchWithContext(ctx, texts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate embeddings: %w", err)
|
||||
var embeddings [][]float32
|
||||
if len(texts) > 0 {
|
||||
if embeddings, err = c.embedSvc.EmbedBatchWithContext(ctx, texts); err != nil {
|
||||
return fmt.Errorf("generate embeddings: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire write lock for DB operations only
|
||||
@@ -165,7 +180,7 @@ func (c *Client) AddDocuments(ctx context.Context, docs []Document) error {
|
||||
|
||||
// Insert into vectors table with model version tracking
|
||||
const insertQuery = `
|
||||
INSERT OR REPLACE INTO vectors (doc_id, embedding, sqlite_id, doc_type, field_type, project, scope, model_version)
|
||||
INSERT INTO vectors (doc_id, embedding, sqlite_id, doc_type, field_type, project, scope, model_version)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`
|
||||
|
||||
@@ -176,6 +191,8 @@ func (c *Client) AddDocuments(ctx context.Context, docs []Document) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("begin transaction: %w", err)
|
||||
}
|
||||
// err is the named result, so every failed return below reaches this and the write lock is released. (A shadowed
|
||||
// err in the loop once left the transaction open, and the database locked, after a failed insert.)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if rbErr := tx.Rollback(); rbErr != nil {
|
||||
@@ -185,6 +202,12 @@ func (c *Client) AddDocuments(ctx context.Context, docs []Document) error {
|
||||
}
|
||||
}()
|
||||
|
||||
if docType != "" {
|
||||
if _, err = tx.ExecContext(ctx, `DELETE FROM vectors WHERE doc_type = ? AND sqlite_id = ?`, docType, sqliteID); err != nil {
|
||||
return fmt.Errorf("delete old documents: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
stmt, err := tx.PrepareContext(ctx, insertQuery)
|
||||
if err != nil {
|
||||
return fmt.Errorf("prepare statement: %w", err)
|
||||
@@ -193,29 +216,28 @@ func (c *Client) AddDocuments(ctx context.Context, docs []Document) error {
|
||||
|
||||
for i, doc := range docs {
|
||||
// Serialize embedding to blob format
|
||||
embBlob, err := sqlite_vec.SerializeFloat32(embeddings[i])
|
||||
if err != nil {
|
||||
var embBlob []byte
|
||||
if embBlob, err = sqlite_vec.SerializeFloat32(embeddings[i]); err != nil {
|
||||
return fmt.Errorf("serialize embedding for %s: %w", doc.ID, err)
|
||||
}
|
||||
|
||||
// Extract metadata
|
||||
sqliteID, _ := doc.Metadata["sqlite_id"].(int64)
|
||||
docType, _ := doc.Metadata["doc_type"].(string)
|
||||
docSQLiteID, _ := doc.Metadata["sqlite_id"].(int64)
|
||||
docDocType, _ := doc.Metadata["doc_type"].(string)
|
||||
fieldType, _ := doc.Metadata["field_type"].(string)
|
||||
project, _ := doc.Metadata["project"].(string)
|
||||
scope, _ := doc.Metadata["scope"].(string)
|
||||
|
||||
_, err = stmt.ExecContext(ctx,
|
||||
if _, err = stmt.ExecContext(ctx,
|
||||
doc.ID,
|
||||
embBlob,
|
||||
sqliteID,
|
||||
docType,
|
||||
docSQLiteID,
|
||||
docDocType,
|
||||
fieldType,
|
||||
project,
|
||||
scope,
|
||||
modelVersion,
|
||||
)
|
||||
if err != nil {
|
||||
); err != nil {
|
||||
return fmt.Errorf("insert document %s: %w", doc.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2152,3 +2152,67 @@ func TestGetOrComputeEmbedding_ContextCancelDuringSingleflight(t *testing.T) {
|
||||
// Wait for first call to finish
|
||||
<-firstDone
|
||||
}
|
||||
|
||||
func TestClient_AddDocuments_FailedBatchIsRolledBackAndDoesNotLockTheDatabase(t *testing.T) {
|
||||
db, dbCleanup := testDB(t)
|
||||
defer dbCleanup()
|
||||
embedSvc, embedCleanup := testEmbeddingService(t)
|
||||
defer embedCleanup()
|
||||
client, err := NewClient(Config{DB: db}, embedSvc)
|
||||
require.NoError(t, err)
|
||||
|
||||
doc := func(id string, sqliteID int64) Document {
|
||||
return Document{ID: id, Content: "text of " + id, Metadata: map[string]any{
|
||||
"sqlite_id": sqliteID, "doc_type": "observation", "field_type": "narrative", "project": "alpha", "scope": "project",
|
||||
}}
|
||||
}
|
||||
require.NoError(t, client.AddDocuments(context.Background(), []Document{doc("obs_1_narrative", 1)}))
|
||||
|
||||
// The second document of the batch exists already, so the batch fails after the first was inserted.
|
||||
err = client.AddDocuments(context.Background(), []Document{doc("obs_2_narrative", 2), doc("obs_1_narrative", 1)})
|
||||
require.Error(t, err)
|
||||
|
||||
var n int
|
||||
require.NoError(t, db.QueryRow("SELECT COUNT(*) FROM vectors WHERE doc_id = 'obs_2_narrative'").Scan(&n))
|
||||
assert.Zero(t, n, "nothing of the failed batch is kept")
|
||||
|
||||
// With the transaction left open, this would wait for the lock until the context ends.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
require.NoError(t, client.AddDocuments(ctx, []Document{doc("obs_3_narrative", 3)}), "a write after a failed one goes through")
|
||||
}
|
||||
|
||||
func TestClient_ReplaceDocuments_ReplacesOnlyTheDocumentsOfThatNote(t *testing.T) {
|
||||
db, dbCleanup := testDB(t)
|
||||
defer dbCleanup()
|
||||
embedSvc, embedCleanup := testEmbeddingService(t)
|
||||
defer embedCleanup()
|
||||
client, err := NewClient(Config{DB: db}, embedSvc)
|
||||
require.NoError(t, err)
|
||||
ctx := context.Background()
|
||||
|
||||
doc := func(id string, sqliteID int64, docType, scope string) Document {
|
||||
return Document{ID: id, Content: "text of " + id, Metadata: map[string]any{
|
||||
"sqlite_id": sqliteID, "doc_type": docType, "field_type": "narrative", "project": "alpha", "scope": scope,
|
||||
}}
|
||||
}
|
||||
require.NoError(t, client.AddDocuments(ctx, []Document{
|
||||
doc("obs_1_narrative", 1, "observation", "global"), doc("obs_1_fact_0", 1, "observation", "global"),
|
||||
doc("obs_2_narrative", 2, "observation", "global"),
|
||||
doc("summary_1_request", 1, "session_summary", ""), // the same sqlite id, another kind of document
|
||||
}))
|
||||
|
||||
require.NoError(t, client.ReplaceDocuments(ctx, "observation", 1, []Document{doc("obs_1_narrative", 1, "observation", "project")}))
|
||||
|
||||
count := func(where string, args ...any) (n int) {
|
||||
require.NoError(t, db.QueryRow("SELECT COUNT(*) FROM vectors WHERE "+where, args...).Scan(&n))
|
||||
return n
|
||||
}
|
||||
assert.Equal(t, 1, count("doc_type = 'observation' AND sqlite_id = 1"), "the fact document is gone")
|
||||
assert.Equal(t, 1, count("doc_id = 'obs_1_narrative' AND scope = 'project'"), "and the narrative carries the new scope")
|
||||
assert.Equal(t, 1, count("doc_id = 'obs_2_narrative' AND scope = 'global'"), "another note is untouched")
|
||||
assert.Equal(t, 1, count("doc_id = 'summary_1_request'"), "so is a summary with the same id")
|
||||
|
||||
require.NoError(t, client.ReplaceDocuments(ctx, "observation", 1, nil), "no documents left: only the old ones are deleted")
|
||||
assert.Zero(t, count("doc_type = 'observation' AND sqlite_id = 1"))
|
||||
}
|
||||
|
||||
@@ -22,11 +22,8 @@ func NewSync(client *Client) *Sync {
|
||||
// SyncObservation syncs a single observation to the vector store.
|
||||
func (s *Sync) SyncObservation(ctx context.Context, obs *models.Observation) error {
|
||||
docs := s.formatObservationDocs(obs)
|
||||
if len(docs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.client.AddDocuments(ctx, docs); err != nil {
|
||||
// Replace, not add: a note that is synced again (after an edit, a re-scope or a re-import) already has documents.
|
||||
if err := s.client.ReplaceDocuments(ctx, "observation", obs.ID, docs); err != nil {
|
||||
return fmt.Errorf("add observation docs: %w", err)
|
||||
}
|
||||
|
||||
@@ -102,11 +99,7 @@ func (s *Sync) formatObservationDocs(obs *models.Observation) []Document {
|
||||
// SyncSummary syncs a single session summary to the vector store.
|
||||
func (s *Sync) SyncSummary(ctx context.Context, summary *models.SessionSummary) error {
|
||||
docs := s.formatSummaryDocs(summary)
|
||||
if len(docs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.client.AddDocuments(ctx, docs); err != nil {
|
||||
if err := s.client.ReplaceDocuments(ctx, "session_summary", summary.ID, docs); err != nil {
|
||||
return fmt.Errorf("add summary docs: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -346,3 +346,57 @@ func TestSync_FormatObservationDocs_EmptyScope(t *testing.T) {
|
||||
assert.Len(t, docs, 1)
|
||||
assert.Equal(t, "project", docs[0].Metadata["scope"])
|
||||
}
|
||||
|
||||
func vectorCount(t *testing.T, c *Client, where string, args ...any) int {
|
||||
t.Helper()
|
||||
var n int
|
||||
require.NoError(t, c.db.QueryRow("SELECT COUNT(*) FROM vectors WHERE "+where, args...).Scan(&n))
|
||||
return n
|
||||
}
|
||||
|
||||
func TestSync_SyncObservation_AgainReplacesTheDocumentsOfTheNote(t *testing.T) {
|
||||
client, cleanup := testClient(t)
|
||||
defer cleanup()
|
||||
sync := NewSync(client)
|
||||
ctx := context.Background()
|
||||
|
||||
obs := &models.Observation{
|
||||
ID: 7, SDKSessionID: "s", Project: "alpha", Type: models.ObsTypeDiscovery, Scope: models.ScopeGlobal,
|
||||
Narrative: sql.NullString{String: "The queue keeps one consumer per tenant.", Valid: true},
|
||||
Facts: []string{"one consumer per tenant", "retries are capped", "dead letters go to a second queue"},
|
||||
}
|
||||
other := &models.Observation{
|
||||
ID: 8, SDKSessionID: "s", Project: "alpha", Type: models.ObsTypeDiscovery, Scope: models.ScopeProject,
|
||||
Narrative: sql.NullString{String: "Releases are cut on Thursdays.", Valid: true},
|
||||
}
|
||||
require.NoError(t, sync.SyncObservation(ctx, obs))
|
||||
require.NoError(t, sync.SyncObservation(ctx, other))
|
||||
require.Equal(t, 4, vectorCount(t, client, "doc_type = 'observation' AND sqlite_id = ?", 7))
|
||||
|
||||
// The note was edited: one fact fewer, and it is a project note now.
|
||||
obs.Facts = obs.Facts[:2]
|
||||
obs.Scope = models.ScopeProject
|
||||
require.NoError(t, sync.SyncObservation(ctx, obs), "syncing a note that already has documents is not an error")
|
||||
|
||||
assert.Equal(t, 3, vectorCount(t, client, "doc_type = 'observation' AND sqlite_id = ?", 7), "narrative and two facts; the dropped fact's document is gone")
|
||||
assert.Equal(t, 0, vectorCount(t, client, "doc_id = ?", "obs_7_fact_2"))
|
||||
assert.Equal(t, 3, vectorCount(t, client, "sqlite_id = ? AND scope = 'project'", 7), "the new scope is what the vectors carry")
|
||||
assert.Equal(t, 1, vectorCount(t, client, "sqlite_id = ?", 8), "other notes are not touched")
|
||||
}
|
||||
|
||||
func TestSync_SyncSummary_AgainReplacesTheDocumentsOfTheSummary(t *testing.T) {
|
||||
client, cleanup := testClient(t)
|
||||
defer cleanup()
|
||||
sync := NewSync(client)
|
||||
ctx := context.Background()
|
||||
|
||||
summary := &models.SessionSummary{
|
||||
ID: 3, SDKSessionID: "s", Project: "alpha",
|
||||
Request: sql.NullString{String: "Add the queue", Valid: true}, Learned: sql.NullString{String: "One consumer per tenant", Valid: true},
|
||||
}
|
||||
require.NoError(t, sync.SyncSummary(ctx, summary))
|
||||
summary.Learned = sql.NullString{}
|
||||
require.NoError(t, sync.SyncSummary(ctx, summary))
|
||||
|
||||
assert.Equal(t, 1, vectorCount(t, client, "doc_type = 'session_summary' AND sqlite_id = ?", 3), "the field that was emptied has no document any more")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -206,14 +207,13 @@ func (pcrl *PerClientRateLimiter) Stats() map[string]any {
|
||||
}
|
||||
|
||||
// PerClientRateLimitMiddleware creates middleware that applies per-client rate limiting.
|
||||
// Uses X-Forwarded-For or RemoteAddr to identify clients.
|
||||
// Identifies clients by the peer IP of the connection; forwarding headers are spoofable and ignored.
|
||||
func PerClientRateLimitMiddleware(limiter *PerClientRateLimiter) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Get client identifier (prefer X-Real-IP from RealIP middleware)
|
||||
clientKey := r.RemoteAddr
|
||||
if xff := r.Header.Get("X-Real-IP"); xff != "" {
|
||||
clientKey = xff
|
||||
if host, _, err := net.SplitHostPort(clientKey); err == nil {
|
||||
clientKey = host
|
||||
}
|
||||
|
||||
if !limiter.Allow(clientKey) {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPerClientRateLimitMiddleware_KeysOnPeerIP(t *testing.T) {
|
||||
h := PerClientRateLimitMiddleware(NewPerClientRateLimiter(0.001, 1))(
|
||||
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) }))
|
||||
|
||||
do := func(remote, realIP string) int {
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
req.RemoteAddr = remote
|
||||
if realIP != "" {
|
||||
req.Header.Set("X-Real-IP", realIP)
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
return rec.Code
|
||||
}
|
||||
|
||||
if got := do("10.0.0.1:1111", "1.1.1.1"); got != http.StatusOK {
|
||||
t.Fatalf("first request: got %d", got)
|
||||
}
|
||||
// Same peer, new port and forged header: must share the exhausted bucket.
|
||||
if got := do("10.0.0.1:2222", "2.2.2.2"); got != http.StatusTooManyRequests {
|
||||
t.Fatalf("spoofed header/new port bypassed limit: got %d", got)
|
||||
}
|
||||
// Different peer is unaffected.
|
||||
if got := do("10.0.0.2:1111", ""); got != http.StatusOK {
|
||||
t.Fatalf("other peer: got %d", got)
|
||||
}
|
||||
}
|
||||
@@ -1226,7 +1226,7 @@ func (s *Service) setupMiddleware() {
|
||||
// Add gzip compression for responses >1KB (reduces bandwidth ~70% for JSON)
|
||||
s.router.Use(middleware.Compress(5)) // Level 5 = good balance of speed vs compression
|
||||
|
||||
// Apply per-client rate limiting (after RealIP so we get the real client IP)
|
||||
// Apply per-client rate limiting (keyed on the socket peer address; forwarding headers are untrusted)
|
||||
if s.rateLimiter != nil {
|
||||
s.router.Use(PerClientRateLimitMiddleware(s.rateLimiter))
|
||||
}
|
||||
|
||||
+10
-10
@@ -13,7 +13,7 @@
|
||||
{
|
||||
"name": "claude-mnemonic",
|
||||
"description": "Persistent memory system for Claude Code - Go implementation with SQLite and ChromaDB vector search",
|
||||
"version": "0.21.77",
|
||||
"version": "0.21.95",
|
||||
"author": {
|
||||
"name": "lukaszraczylo",
|
||||
"url": "https://github.com/lukaszraczylo"
|
||||
@@ -23,25 +23,25 @@
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/lukaszraczylo/claude-mnemonic",
|
||||
"releases": {
|
||||
"latest": "0.21.77",
|
||||
"latest": "0.21.95",
|
||||
"versions": {
|
||||
"0.21.77": {
|
||||
"releaseDate": "2026-10-03",
|
||||
"0.21.95": {
|
||||
"releaseDate": "2026-10-04",
|
||||
"downloads": {
|
||||
"darwin-arm64": {
|
||||
"url": "https://github.com/lukaszraczylo/claude-mnemonic/releases/download/v0.21.77/claude-mnemonic_0.21.77_darwin_arm64.tar.gz",
|
||||
"url": "https://github.com/lukaszraczylo/claude-mnemonic/releases/download/v0.21.95/claude-mnemonic_0.21.95_darwin_arm64.tar.gz",
|
||||
"format": "tar.gz",
|
||||
"sha256": "7bf9c814f4c2d1e9a727c24b0b487bd207dbdc45ed0828aef23e53017f3019d7"
|
||||
"sha256": "3224be650ead03a23078f7033909ecaedf89c88d665b3aa83c70b2eb952722b9"
|
||||
},
|
||||
"linux-amd64": {
|
||||
"url": "https://github.com/lukaszraczylo/claude-mnemonic/releases/download/v0.21.77/claude-mnemonic_0.21.77_linux_amd64.tar.gz",
|
||||
"url": "https://github.com/lukaszraczylo/claude-mnemonic/releases/download/v0.21.95/claude-mnemonic_0.21.95_linux_amd64.tar.gz",
|
||||
"format": "tar.gz",
|
||||
"sha256": "cf5998292c72662b85a25df539a340b8c24e9caa2488fed9fd817d758124eac2"
|
||||
"sha256": "4af6927b7857b03143e6eb817da7f44c39dd2b5674a7d1b7f505db7c3dd25b2f"
|
||||
},
|
||||
"windows-amd64": {
|
||||
"url": "https://github.com/lukaszraczylo/claude-mnemonic/releases/download/v0.21.77/claude-mnemonic_0.21.77_windows_amd64.zip",
|
||||
"url": "https://github.com/lukaszraczylo/claude-mnemonic/releases/download/v0.21.95/claude-mnemonic_0.21.95_windows_amd64.zip",
|
||||
"format": "zip",
|
||||
"sha256": "762ca4da50188763928802f148ec918e9f02d7678400fe17e46f84d82f5ed57b"
|
||||
"sha256": "d779920957eea6b21a344556b5a36ec2a1a6c596e095575e73110c5cb997fc1a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+152
-86
@@ -15,7 +15,7 @@
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-free": "^7.3.1",
|
||||
"@tailwindcss/postcss": "^4.3.3",
|
||||
"@types/node": "^25.9.8",
|
||||
"@types/node": "^26.0.0",
|
||||
"@vitejs/plugin-vue": "^6.0.9",
|
||||
"postcss": "^8.5.28",
|
||||
"tailwindcss": "^4.3.3",
|
||||
@@ -156,9 +156,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.150.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.150.0.tgz",
|
||||
"integrity": "sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw==",
|
||||
"version": "0.152.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz",
|
||||
"integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@@ -166,9 +166,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm-eabi": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.9.tgz",
|
||||
"integrity": "sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz",
|
||||
"integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -183,9 +183,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm64": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.9.tgz",
|
||||
"integrity": "sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz",
|
||||
"integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -200,9 +200,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.9.tgz",
|
||||
"integrity": "sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz",
|
||||
"integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -217,9 +217,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-x64": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.9.tgz",
|
||||
"integrity": "sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz",
|
||||
"integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -234,9 +234,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.9.tgz",
|
||||
"integrity": "sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz",
|
||||
"integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -251,9 +251,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.9.tgz",
|
||||
"integrity": "sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz",
|
||||
"integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -268,9 +268,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.9.tgz",
|
||||
"integrity": "sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -288,9 +288,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.9.tgz",
|
||||
"integrity": "sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz",
|
||||
"integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -308,9 +308,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.9.tgz",
|
||||
"integrity": "sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -328,9 +328,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.9.tgz",
|
||||
"integrity": "sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -348,9 +348,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.9.tgz",
|
||||
"integrity": "sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -368,9 +368,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.9.tgz",
|
||||
"integrity": "sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz",
|
||||
"integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -388,9 +388,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.9.tgz",
|
||||
"integrity": "sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz",
|
||||
"integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -405,9 +405,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.9.tgz",
|
||||
"integrity": "sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz",
|
||||
"integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -422,9 +422,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.9.tgz",
|
||||
"integrity": "sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz",
|
||||
"integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -680,6 +680,72 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
|
||||
"version": "1.11.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
|
||||
"version": "1.11.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.4",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz",
|
||||
@@ -736,13 +802,13 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.8.tgz",
|
||||
"integrity": "sha512-VfMrScDmMhUJQmd5hArdQnFvK0OIeD36uN2Va1FcpYaLB/BgkgM8Ulc50XtYISPMz7APJ30+N0T5EM0jlcdfRw==",
|
||||
"version": "26.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.4.tgz",
|
||||
"integrity": "sha512-ldVPDCzj7fsaGZrLB0NuHuTvJcsNasysBAqMolr/cgxrLd1xbqxIr3XJiPnHHJUCxj5sNF1vnRj9aWnrVh5Jcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": ">=7.24.0 <7.24.7"
|
||||
"undici-types": "~8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
@@ -842,9 +908,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.11.tgz",
|
||||
"integrity": "sha512-QJmpliwAVpC/OxubIByPAhNzsQPRc8/gxlN2qnVzVfIMjMDz/9RnXRFoetjz5yEgXVXyp4LqhXq3V53PjmNzFw==",
|
||||
"version": "3.3.12",
|
||||
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.12.tgz",
|
||||
"integrity": "sha512-k7uIKR0n4CBidk233y7cac9osnDQ5WRidTl6nsrNvpZ3nf8cx9iJxRVsRzVsoPRHbowT/iKgGMTS9RGov3jeIA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1392,13 +1458,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.9.tgz",
|
||||
"integrity": "sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==",
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz",
|
||||
"integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.150.0",
|
||||
"@oxc-project/types": "=0.152.0",
|
||||
"@rolldown/pluginutils": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -1408,21 +1474,21 @@
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.9",
|
||||
"@rolldown/binding-android-arm64": "1.2.9",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.9",
|
||||
"@rolldown/binding-darwin-x64": "1.2.9",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.9",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.9",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.9",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.9",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.9",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.9",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.9",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.9",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.9",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.9",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.9"
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.12",
|
||||
"@rolldown/binding-android-arm64": "1.2.12",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.12",
|
||||
"@rolldown/binding-darwin-x64": "1.2.12",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.12",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.12",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.12",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.12",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.12",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.12",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.12"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
@@ -1487,9 +1553,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.24.6",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
||||
"version": "8.9.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz",
|
||||
"integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -1558,16 +1624,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.0.tgz",
|
||||
"integrity": "sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==",
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.2.tgz",
|
||||
"integrity": "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.33.0",
|
||||
"picomatch": "^4.0.7",
|
||||
"postcss": "^8.5.28",
|
||||
"rolldown": "~1.2.6",
|
||||
"rolldown": "~1.2.11",
|
||||
"tinyglobby": "^0.2.17"
|
||||
},
|
||||
"bin": {
|
||||
@@ -1937,14 +2003,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.11.tgz",
|
||||
"integrity": "sha512-gOb0B9rtU2+f1dszwPqSH5kAieIF9ReeLhD3kSRNHv5WZZUQz/JdVXW0RTdqhNTMlQkqKzrTTviqKr/4FYZraQ==",
|
||||
"version": "3.3.12",
|
||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.12.tgz",
|
||||
"integrity": "sha512-kbpaz18O9jPVkXVHD1BEjpUXM6WhXSu+62L1sGGr6Wbzd8GbvkBQWjoj3KZ/C0aq2MZllce7UdtWzwCIYsBMGA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/typescript": "2.4.28",
|
||||
"@vue/language-core": "3.3.11"
|
||||
"@vue/language-core": "3.3.12"
|
||||
},
|
||||
"bin": {
|
||||
"vue-tsc": "bin/vue-tsc.js"
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-free": "^7.3.1",
|
||||
"@tailwindcss/postcss": "^4.3.3",
|
||||
"@types/node": "^25.9.8",
|
||||
"@types/node": "^26.0.0",
|
||||
"@vitejs/plugin-vue": "^6.0.9",
|
||||
"postcss": "^8.5.28",
|
||||
"tailwindcss": "^4.3.3",
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-free": "^7.3.1",
|
||||
"@tailwindcss/postcss": "^4.3.3",
|
||||
"@types/node": "^25.9.8",
|
||||
"@types/node": "^26.0.0",
|
||||
"@vitejs/plugin-vue": "^6.0.9",
|
||||
"postcss": "^8.5.28",
|
||||
"tailwindcss": "^4.3.3",
|
||||
|
||||
Reference in New Issue
Block a user