diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 2cd3392b..05a07e19 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -71,5 +71,5 @@ jobs: - name: Build all packages run: pnpm -r --filter './packages/**' build - - name: Publish to local Gitea registry - run: bash ./scripts/gitea/publish-local-packages.sh + - name: Publish outdated packages to Gitea registry + run: bash ./scripts/gitea/publish-outdated-packages.sh --skip-build diff --git a/packages/accessibility/package.json b/packages/accessibility/package.json index ccb118db..365bed67 100644 --- a/packages/accessibility/package.json +++ b/packages/accessibility/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/accessibility", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/api-client/package.json b/packages/api-client/package.json index ae57002d..0261f1fb 100644 --- a/packages/api-client/package.json +++ b/packages/api-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/api-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/auth-client/package.json b/packages/auth-client/package.json index 3a0e0208..bc36103d 100644 --- a/packages/auth-client/package.json +++ b/packages/auth-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/auth-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe auth API client for platform-service", "exports": { diff --git a/packages/auth-ui/package.json b/packages/auth-ui/package.json index 4320a478..3f6285ad 100644 --- a/packages/auth-ui/package.json +++ b/packages/auth-ui/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/auth-ui", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Shared auth UI components for SmartAuth (LoginForm, MfaChallenge, SocialButtons)", "exports": { diff --git a/packages/auth/package.json b/packages/auth/package.json index acca98c3..86164e63 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/auth", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/backend-config/package.json b/packages/backend-config/package.json index 585c970c..fe644618 100644 --- a/packages/backend-config/package.json +++ b/packages/backend-config/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/backend-config", - "version": "0.1.2", + "version": "0.1.5", "description": "Shared Zod config schema base for Fastify product backends", "type": "module", "main": "dist/index.js", diff --git a/packages/backend-flags/package.json b/packages/backend-flags/package.json index 616570b9..96f1aff1 100644 --- a/packages/backend-flags/package.json +++ b/packages/backend-flags/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/backend-flags", - "version": "0.1.2", + "version": "0.1.5", "description": "In-memory feature flag registry for Fastify product backends", "type": "module", "main": "dist/index.js", diff --git a/packages/backend-telemetry/package.json b/packages/backend-telemetry/package.json index 58277f77..64e2400d 100644 --- a/packages/backend-telemetry/package.json +++ b/packages/backend-telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/backend-telemetry", - "version": "0.1.2", + "version": "0.1.5", "description": "In-memory telemetry event buffer for Fastify product backends", "type": "module", "main": "dist/index.js", diff --git a/packages/blob-client/package.json b/packages/blob-client/package.json index bdc89ecf..82f8bcde 100644 --- a/packages/blob-client/package.json +++ b/packages/blob-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/blob-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe blob storage client — SAS URL upload/download via platform-service", "exports": { diff --git a/packages/blob/package.json b/packages/blob/package.json index 20e00be6..8df2583c 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/blob", - "version": "0.2.2", + "version": "0.2.5", "type": "module", "exports": { ".": { diff --git a/packages/broadcast-client/package.json b/packages/broadcast-client/package.json index b8ade879..202a9f86 100644 --- a/packages/broadcast-client/package.json +++ b/packages/broadcast-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/broadcast-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe broadcast messaging client for platform-service", "exports": { diff --git a/packages/celebrations/package.json b/packages/celebrations/package.json index c974e362..9a150c5b 100644 --- a/packages/celebrations/package.json +++ b/packages/celebrations/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/celebrations", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/client-encrypt/package.json b/packages/client-encrypt/package.json index 98dd9f8d..a1d29370 100644 --- a/packages/client-encrypt/package.json +++ b/packages/client-encrypt/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/client-encrypt", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/config/package.json b/packages/config/package.json index 093df79b..433cbda7 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/config", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/cosmos/package.json b/packages/cosmos/package.json index 676a645b..838e959d 100644 --- a/packages/cosmos/package.json +++ b/packages/cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/cosmos", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/create-app/package.json b/packages/create-app/package.json index cc9eee73..e731df43 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/create-app", - "version": "0.1.0", + "version": "0.1.3", "description": "CLI tools for scaffolding ByteLyst product repos and code", "type": "module", "bin": { diff --git a/packages/dashboard-components/package.json b/packages/dashboard-components/package.json index 700af5b5..92002a24 100644 --- a/packages/dashboard-components/package.json +++ b/packages/dashboard-components/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/dashboard-components", - "version": "0.1.2", + "version": "0.1.5", "description": "Shared React components for ByteLyst dashboards", "type": "module", "main": "./dist/index.js", diff --git a/packages/dashboard-shell/package.json b/packages/dashboard-shell/package.json index fbf4bb98..c183f4f4 100644 --- a/packages/dashboard-shell/package.json +++ b/packages/dashboard-shell/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/dashboard-shell", - "version": "0.1.2", + "version": "0.1.5", "description": "Configurable Next.js dashboard layout with sidebar, profile, billing, and settings pages", "type": "module", "main": "./dist/index.js", diff --git a/packages/datastore/package.json b/packages/datastore/package.json index 14ef113b..ed43c01f 100644 --- a/packages/datastore/package.json +++ b/packages/datastore/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/datastore", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/design-tokens/package.json b/packages/design-tokens/package.json index e2d775c9..55a6e3a5 100644 --- a/packages/design-tokens/package.json +++ b/packages/design-tokens/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/design-tokens", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/diagnostics-client/package.json b/packages/diagnostics-client/package.json index c0b71426..079dbd5f 100644 --- a/packages/diagnostics-client/package.json +++ b/packages/diagnostics-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/diagnostics-client", - "version": "0.1.2", + "version": "0.1.5", "description": "TypeScript client for remote diagnostics and debug tracing", "type": "module", "exports": { diff --git a/packages/errors/package.json b/packages/errors/package.json index 4cba8c56..17822528 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/errors", - "version": "0.1.3", + "version": "0.1.6", "type": "module", "exports": { ".": { diff --git a/packages/event-store/package.json b/packages/event-store/package.json index e145db1f..5f94b35f 100644 --- a/packages/event-store/package.json +++ b/packages/event-store/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/event-store", - "version": "0.1.2", + "version": "0.1.5", "description": "Persistent event store with pluggable backends (in-memory, file, Cosmos) for ByteLyst product backends", "type": "module", "exports": { diff --git a/packages/events/package.json b/packages/events/package.json index e10e1cc3..444153ff 100644 --- a/packages/events/package.json +++ b/packages/events/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/events", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/extraction/package.json b/packages/extraction/package.json index ee1877bb..f83be5c0 100644 --- a/packages/extraction/package.json +++ b/packages/extraction/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/extraction", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Shared types and client for the extraction service", "exports": { diff --git a/packages/fastify-auth/package.json b/packages/fastify-auth/package.json index ebce954d..59edb9bd 100644 --- a/packages/fastify-auth/package.json +++ b/packages/fastify-auth/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/fastify-auth", - "version": "0.1.2", + "version": "0.1.5", "description": "JWT auth middleware + request context for Fastify product backends", "type": "module", "main": "dist/index.js", diff --git a/packages/fastify-core/package.json b/packages/fastify-core/package.json index 77e0a319..20a6dfc8 100644 --- a/packages/fastify-core/package.json +++ b/packages/fastify-core/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/fastify-core", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/fastify-sse/package.json b/packages/fastify-sse/package.json index 892f457b..279e2e82 100644 --- a/packages/fastify-sse/package.json +++ b/packages/fastify-sse/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/fastify-sse", - "version": "0.3.2", + "version": "0.3.5", "description": "Fastify plugin for Server-Sent Events (SSE) — real-time push for ByteLyst product backends", "type": "module", "exports": { diff --git a/packages/feature-flag-client/package.json b/packages/feature-flag-client/package.json index 966349d1..c9b7097e 100644 --- a/packages/feature-flag-client/package.json +++ b/packages/feature-flag-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/feature-flag-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe feature flag client for platform-service", "exports": { diff --git a/packages/feedback-client/package.json b/packages/feedback-client/package.json index 8a5cd193..3dafade1 100644 --- a/packages/feedback-client/package.json +++ b/packages/feedback-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/feedback-client", - "version": "0.1.2", + "version": "0.1.5", "description": "TypeScript client for submitting user feedback with screenshots", "type": "module", "exports": { diff --git a/packages/field-encrypt/package.json b/packages/field-encrypt/package.json index ffe52839..0a184be0 100644 --- a/packages/field-encrypt/package.json +++ b/packages/field-encrypt/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/field-encrypt", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/gentle-notifications/package.json b/packages/gentle-notifications/package.json index d2a4fa4c..71dd299d 100644 --- a/packages/gentle-notifications/package.json +++ b/packages/gentle-notifications/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/gentle-notifications", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/kill-switch-client/package.json b/packages/kill-switch-client/package.json index 7a133207..5e2458cd 100644 --- a/packages/kill-switch-client/package.json +++ b/packages/kill-switch-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/kill-switch-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe kill switch client for platform-service", "exports": { diff --git a/packages/llm-router/package.json b/packages/llm-router/package.json index fc69ac91..873e1f98 100644 --- a/packages/llm-router/package.json +++ b/packages/llm-router/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/llm-router", - "version": "0.1.2", + "version": "0.1.5", "description": "Pure-code LLM router for free-tier API providers with round-robin, fallback, and health tracking", "type": "module", "exports": { diff --git a/packages/llm/package.json b/packages/llm/package.json index f6be5122..215c0c14 100644 --- a/packages/llm/package.json +++ b/packages/llm/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/llm", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/logger/package.json b/packages/logger/package.json index 514eb747..20446d0a 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/logger", - "version": "0.1.2", + "version": "0.1.5", "description": "Structured logger factory for Next.js dashboards and Node.js services", "type": "module", "exports": { diff --git a/packages/marketplace-client/package.json b/packages/marketplace-client/package.json index ae4c9bd9..40363365 100644 --- a/packages/marketplace-client/package.json +++ b/packages/marketplace-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/marketplace-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/monitoring/package.json b/packages/monitoring/package.json index b3957184..1d9b8771 100644 --- a/packages/monitoring/package.json +++ b/packages/monitoring/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/monitoring", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Health-check aggregation utilities for ByteLyst services and dashboards", "exports": { diff --git a/packages/offline-queue/package.json b/packages/offline-queue/package.json index 927c7c40..4aadb6af 100644 --- a/packages/offline-queue/package.json +++ b/packages/offline-queue/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/offline-queue", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe persistent offline retry queue", "exports": { diff --git a/packages/ollama-client/package.json b/packages/ollama-client/package.json index 018b7fd5..a449ce00 100644 --- a/packages/ollama-client/package.json +++ b/packages/ollama-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/ollama-client", - "version": "0.1.3", + "version": "0.1.6", "description": "Shared Ollama API client — streaming chat, embeddings, model management, health checks", "type": "module", "exports": { diff --git a/packages/org-client/package.json b/packages/org-client/package.json index d45404c9..a12b5f15 100644 --- a/packages/org-client/package.json +++ b/packages/org-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/org-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/palace/package.json b/packages/palace/package.json index 1f9ae3bf..813a38b1 100644 --- a/packages/palace/package.json +++ b/packages/palace/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/palace", - "version": "0.1.1", + "version": "0.1.4", "description": "Shared MemPalace primitives — types, cosine similarity, dedup, relevance decay, extraction prompts, KG helpers, wake-up context builder", "type": "module", "exports": { diff --git a/packages/platform-client/package.json b/packages/platform-client/package.json index 239a7f15..79195c15 100644 --- a/packages/platform-client/package.json +++ b/packages/platform-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/platform-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe typed fetch wrapper for platform-service", "exports": { diff --git a/packages/push/package.json b/packages/push/package.json index e830f420..d8cb2844 100644 --- a/packages/push/package.json +++ b/packages/push/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/push", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/queue/package.json b/packages/queue/package.json index b7d3c769..3f13bc97 100644 --- a/packages/queue/package.json +++ b/packages/queue/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/queue", - "version": "0.1.2", + "version": "0.1.5", "description": "Durable job queue with pluggable stores and worker runtime", "type": "module", "exports": { diff --git a/packages/quick-actions/package.json b/packages/quick-actions/package.json index 3cd157d8..0237e0c1 100644 --- a/packages/quick-actions/package.json +++ b/packages/quick-actions/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/quick-actions", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/react-auth/package.json b/packages/react-auth/package.json index 9440a74f..0d04cc78 100644 --- a/packages/react-auth/package.json +++ b/packages/react-auth/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/react-auth", - "version": "0.1.3", + "version": "0.1.6", "type": "module", "exports": { ".": { diff --git a/packages/referral-client/package.json b/packages/referral-client/package.json index 1e65f266..b922a34c 100644 --- a/packages/referral-client/package.json +++ b/packages/referral-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/referral-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/secure-storage-web/package.json b/packages/secure-storage-web/package.json index 11fe9b40..39a42bd3 100644 --- a/packages/secure-storage-web/package.json +++ b/packages/secure-storage-web/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/secure-storage-web", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/speech/package.json b/packages/speech/package.json index 65664e7e..f4e405e2 100644 --- a/packages/speech/package.json +++ b/packages/speech/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/speech", - "version": "0.1.2", + "version": "0.1.5", "description": "Cloud-agnostic speech-to-text abstraction for the ByteLyst ecosystem", "type": "module", "exports": { diff --git a/packages/storage/package.json b/packages/storage/package.json index 113840a2..4e46626c 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/storage", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/subscription-client/package.json b/packages/subscription-client/package.json index c67f5996..b5dce4ab 100644 --- a/packages/subscription-client/package.json +++ b/packages/subscription-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/subscription-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/survey-client/package.json b/packages/survey-client/package.json index 2f598802..656a9b78 100644 --- a/packages/survey-client/package.json +++ b/packages/survey-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/survey-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe survey client for platform-service", "exports": { diff --git a/packages/sync/package.json b/packages/sync/package.json index f75ecc73..a205f63a 100644 --- a/packages/sync/package.json +++ b/packages/sync/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/sync", - "version": "0.1.2", + "version": "0.1.5", "description": "Offline-first sync engine with configurable storage adapters and conflict resolution", "type": "module", "main": "./dist/index.js", diff --git a/packages/telemetry-client/package.json b/packages/telemetry-client/package.json index 35849625..0ee6c1d9 100644 --- a/packages/telemetry-client/package.json +++ b/packages/telemetry-client/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/telemetry-client", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "description": "Browser/React Native-safe telemetry client for platform-service", "exports": { diff --git a/packages/testing/package.json b/packages/testing/package.json index cb0a1ef3..0e819bc7 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/testing", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "exports": { ".": { diff --git a/packages/time-references/package.json b/packages/time-references/package.json index 426067a5..78f132a8 100644 --- a/packages/time-references/package.json +++ b/packages/time-references/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/time-references", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/ui/package.json b/packages/ui/package.json index 3e7cf825..0d0ea3bc 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/ui", - "version": "0.1.2", + "version": "0.1.5", "type": "module", "scripts": { "storybook": "storybook dev -p 6006", diff --git a/packages/use-keyboard-shortcuts/package.json b/packages/use-keyboard-shortcuts/package.json index d83c31e5..c56657ff 100644 --- a/packages/use-keyboard-shortcuts/package.json +++ b/packages/use-keyboard-shortcuts/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/use-keyboard-shortcuts", - "version": "0.1.3", + "version": "0.1.6", "type": "module", "exports": { ".": { diff --git a/packages/use-theme/package.json b/packages/use-theme/package.json index 478369cc..e70c6dd7 100644 --- a/packages/use-theme/package.json +++ b/packages/use-theme/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/use-theme", - "version": "0.1.3", + "version": "0.1.6", "type": "module", "exports": { ".": { diff --git a/packages/webhook-dispatch/package.json b/packages/webhook-dispatch/package.json index eaa8d167..8f36ccfc 100644 --- a/packages/webhook-dispatch/package.json +++ b/packages/webhook-dispatch/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/webhook-dispatch", - "version": "0.1.2", + "version": "0.1.5", "description": "Reusable webhook dispatch with HMAC-SHA256 signing, exponential backoff retry, and delivery tracking for ByteLyst product backends", "type": "module", "exports": { diff --git a/scripts/gitea/.publish-manifest.json b/scripts/gitea/.publish-manifest.json new file mode 100644 index 00000000..87919589 --- /dev/null +++ b/scripts/gitea/.publish-manifest.json @@ -0,0 +1,307 @@ +{ + "@bytelyst/accessibility": { + "version": "0.1.5", + "contentHash": "1298db3c803a8e338599967527b1af76d41e6ca60afb1566ef8346314845f094", + "publishedAt": "2026-04-13T08:44:02.743Z" + }, + "@bytelyst/api-client": { + "version": "0.1.5", + "contentHash": "60958fa143ab6ff3aa6225779f162fe3a24744fb268f01bdff544b9a69ea0bdd", + "publishedAt": "2026-04-13T08:44:04.429Z" + }, + "@bytelyst/auth": { + "version": "0.1.5", + "contentHash": "97f8e1ca0a609075e82751091a4a995740a5b06b513c14b55ee57ce6a9de7309", + "publishedAt": "2026-04-13T08:44:09.341Z" + }, + "@bytelyst/auth-client": { + "version": "0.1.5", + "contentHash": "0155230525c853d8a18a6861078a5fecb2769962fd0f4102c759ead25c245296", + "publishedAt": "2026-04-13T08:44:06.085Z" + }, + "@bytelyst/auth-ui": { + "version": "0.1.5", + "contentHash": "82bcd4ff0f8dea680c393b2f03470ce17bd1770baf3f9aca40dc1f18f2a82ad9", + "publishedAt": "2026-04-13T08:44:07.686Z" + }, + "@bytelyst/backend-config": { + "version": "0.1.5", + "contentHash": "37808dd0b3280b730122ed0171811ac92dc7fd79e10a78f3c14daef911478149", + "publishedAt": "2026-04-13T08:44:11.057Z" + }, + "@bytelyst/backend-flags": { + "version": "0.1.5", + "contentHash": "f79b89e172df28a296bd343883798bd761685599d27adfd94f88e09ef495df17", + "publishedAt": "2026-04-13T08:44:12.606Z" + }, + "@bytelyst/backend-telemetry": { + "version": "0.1.5", + "contentHash": "34ead309860862742b7bafa60a85b95e5f1ccbd187cf7d849064e039ca1e336a", + "publishedAt": "2026-04-13T08:44:14.003Z" + }, + "@bytelyst/blob": { + "version": "0.2.5", + "contentHash": "62b14ea355c625e102c533e9327f281b13c6031cfc3055fb4a6022d8d7512c5f", + "publishedAt": "2026-04-13T08:44:17.082Z" + }, + "@bytelyst/blob-client": { + "version": "0.1.5", + "contentHash": "4b9e2a79ae68cba537026a861408afbd205f8d9da3f20bcab073d8f95881e6be", + "publishedAt": "2026-04-13T08:44:15.555Z" + }, + "@bytelyst/broadcast-client": { + "version": "0.1.5", + "contentHash": "e819ffca743f96cdeb725134a1692378a2dbb0b40c843721290841e33fa731b7", + "publishedAt": "2026-04-13T08:44:18.467Z" + }, + "@bytelyst/celebrations": { + "version": "0.1.5", + "contentHash": "84570ad46d99cada6b59512a81a5f1fbee2a74a982f9c8ffe1ca9577bc3e537b", + "publishedAt": "2026-04-13T08:44:20.012Z" + }, + "@bytelyst/client-encrypt": { + "version": "0.1.5", + "contentHash": "4cfcfbe8b253dedaccfad21e680c43244449b60d441599a63031d8e27fa11ed1", + "publishedAt": "2026-04-13T08:44:21.557Z" + }, + "@bytelyst/config": { + "version": "0.1.5", + "contentHash": "461d8646a67d0dfb4b27bbb62ee8751428d190c20ba9b55bea556806f55c0355", + "publishedAt": "2026-04-13T08:44:23.220Z" + }, + "@bytelyst/cosmos": { + "version": "0.1.5", + "contentHash": "b0ddd5441f4b15ca28453b6e4cd089fcd92f7b504132d03c43a9b869c111c108", + "publishedAt": "2026-04-13T08:44:24.588Z" + }, + "@bytelyst/create-app": { + "version": "0.1.3", + "contentHash": "e0439baca0c3850dc5714fcbb84b8b996549771740381fe5cf202a03b4e0c841", + "publishedAt": "2026-04-13T08:44:26.178Z" + }, + "@bytelyst/dashboard-components": { + "version": "0.1.5", + "contentHash": "7d1ab88cb6fc6093e66c7be89c1cdc6ef7031bf20783b04d4f05bbb9d2e2dd5c", + "publishedAt": "2026-04-13T08:44:27.860Z" + }, + "@bytelyst/dashboard-shell": { + "version": "0.1.5", + "contentHash": "e88743978d4d09a1a4047e5134469521ba8a9c0520ec04d0d3b7b5e4cb09f841", + "publishedAt": "2026-04-13T08:44:29.385Z" + }, + "@bytelyst/datastore": { + "version": "0.1.5", + "contentHash": "482bef2452f47fe4ca553f3a1c67eb4dbd159ca9b791a274e713fbe0e64a7a2b", + "publishedAt": "2026-04-13T08:44:30.939Z" + }, + "@bytelyst/design-tokens": { + "version": "0.1.5", + "contentHash": "46c2c7041807e52c965f08b8159b4cb17a4b752171f7d18cdb594f96d401792a", + "publishedAt": "2026-04-13T08:44:32.598Z" + }, + "@bytelyst/diagnostics-client": { + "version": "0.1.5", + "contentHash": "c52ebcb6674e3cc468461741c86298f5923e80ca8fa4fbb08d55fdfd39517e7f", + "publishedAt": "2026-04-13T08:44:34.283Z" + }, + "@bytelyst/errors": { + "version": "0.1.6", + "contentHash": "76443c39ff29478a483cb82439dcc44c5a25a1e87cf53eba3c1ba1e30b7947cf", + "publishedAt": "2026-04-13T08:44:35.843Z" + }, + "@bytelyst/event-store": { + "version": "0.1.5", + "contentHash": "8ecf328682c6b886d0ee2db85094b7d2c6f589fe56d7666319b197383d8ca2ff", + "publishedAt": "2026-04-13T08:44:37.491Z" + }, + "@bytelyst/events": { + "version": "0.1.5", + "contentHash": "ea584931f18cf682d3738545474ada10b67a775b7b549f4cc4862e145be8972f", + "publishedAt": "2026-04-13T08:44:39.134Z" + }, + "@bytelyst/extraction": { + "version": "0.1.5", + "contentHash": "0edce9563443f5daea8d5efb2481fedaad9746f4ee1b7b9fb29e9095c0fe9305", + "publishedAt": "2026-04-13T08:44:40.758Z" + }, + "@bytelyst/fastify-auth": { + "version": "0.1.5", + "contentHash": "d196ce76219aa420273d003781b83ecca11f11271dd2be9cfbe0c6b832d6d790", + "publishedAt": "2026-04-13T08:44:42.446Z" + }, + "@bytelyst/fastify-core": { + "version": "0.1.5", + "contentHash": "0140953510ee4cf2f584c6f2745e33817832a7848f13e4a26b805038238cba77", + "publishedAt": "2026-04-13T08:44:44.114Z" + }, + "@bytelyst/fastify-sse": { + "version": "0.3.5", + "contentHash": "1ef6fc1053ec6108af6faae1b6669fed4dc659660b6fbcc96474f7dff5c2d209", + "publishedAt": "2026-04-13T08:44:45.648Z" + }, + "@bytelyst/feature-flag-client": { + "version": "0.1.5", + "contentHash": "81bbef1e411bdf9c38e59f82b6b7427b653aa7f36b304a32202332d260529ba3", + "publishedAt": "2026-04-13T08:44:47.385Z" + }, + "@bytelyst/feedback-client": { + "version": "0.1.5", + "contentHash": "a9e11aa31ae7d576b0502fd6aefdfc93028863ae3e076e39c0accb4d2f78e524", + "publishedAt": "2026-04-13T08:44:49.075Z" + }, + "@bytelyst/field-encrypt": { + "version": "0.1.5", + "contentHash": "3d8a01f2421fa077bf0f149b529f1841ec0f54a84b290b8535ca498e9c714c76", + "publishedAt": "2026-04-13T08:44:50.633Z" + }, + "@bytelyst/gentle-notifications": { + "version": "0.1.5", + "contentHash": "00e49456bba81458c7d0129880207cc4e631ccd1037770ecddbfa9f7fbde8387", + "publishedAt": "2026-04-13T08:44:51.924Z" + }, + "@bytelyst/kill-switch-client": { + "version": "0.1.5", + "contentHash": "0a6a46bcac5eb8d5723dd44458f533b8ef203b796939fb66cf66f2e6223c07fd", + "publishedAt": "2026-04-13T08:44:53.517Z" + }, + "@bytelyst/llm": { + "version": "0.1.5", + "contentHash": "7985c82f98990adf7aa70aa55676c1fdd08e2100644d1b42a786758f7e0bb89c", + "publishedAt": "2026-04-13T08:44:56.327Z" + }, + "@bytelyst/llm-router": { + "version": "0.1.5", + "contentHash": "5cc32aec6c0dd8bff4b4206ff55937663ba2995926d498510e49747a3fc12183", + "publishedAt": "2026-04-13T08:44:54.935Z" + }, + "@bytelyst/logger": { + "version": "0.1.5", + "contentHash": "3ad702d6f0731621499916049049cf8de38a53e4c005095a2a14ca8b0aff1bbd", + "publishedAt": "2026-04-13T08:44:57.723Z" + }, + "@bytelyst/marketplace-client": { + "version": "0.1.5", + "contentHash": "f44881256419432284b40dbde7d677a109579d94a3b9df9f3b9f40641ee30085", + "publishedAt": "2026-04-13T08:44:59.204Z" + }, + "@bytelyst/monitoring": { + "version": "0.1.5", + "contentHash": "08840748c02e326e7cd2c410d80c17c1fcaeb5c48c57f3bbc5a5069926e660da", + "publishedAt": "2026-04-13T08:45:00.504Z" + }, + "@bytelyst/offline-queue": { + "version": "0.1.5", + "contentHash": "1c25e355ec6a6f7c7e74e77b8c53aca94f0342eda049d535e31b56c6632d5101", + "publishedAt": "2026-04-13T08:45:02.179Z" + }, + "@bytelyst/ollama-client": { + "version": "0.1.6", + "contentHash": "fa08340465aba0e866f8c5bb2839425ce46c694a5ad0839283fdbb8037a39121", + "publishedAt": "2026-04-13T08:45:03.855Z" + }, + "@bytelyst/org-client": { + "version": "0.1.5", + "contentHash": "e0b8eb1bce5047e9bfcf11db8f77d8495f403cd08f74bb3d4a0dc37183a9ef29", + "publishedAt": "2026-04-13T08:45:05.581Z" + }, + "@bytelyst/palace": { + "version": "0.1.4", + "contentHash": "8e47ae7ed300b1edd2f2058b5c3358f2d917d7b91ab4218357ad7cc3d20ed085", + "publishedAt": "2026-04-13T08:45:07.168Z" + }, + "@bytelyst/platform-client": { + "version": "0.1.5", + "contentHash": "a5d90ea537a55ea295d5c9933f4ccab2b152d57666db623f7e6bcc11f403025a", + "publishedAt": "2026-04-13T08:45:08.836Z" + }, + "@bytelyst/push": { + "version": "0.1.5", + "contentHash": "8fea33b73c0e4dc758a77b0dc80f49a1ea3a15b51a216dbc875b3f56c260685a", + "publishedAt": "2026-04-13T08:45:10.487Z" + }, + "@bytelyst/queue": { + "version": "0.1.5", + "contentHash": "f3ea3cdf536c117e04f393bf1bfc5eda24117973aad3be15e687513b444f6bdb", + "publishedAt": "2026-04-13T08:45:12.106Z" + }, + "@bytelyst/quick-actions": { + "version": "0.1.5", + "contentHash": "c1daf30dec2eda0bbec55a73e8c0cdb98d7c3c43dbcb5791bb9ef6097e3f4599", + "publishedAt": "2026-04-13T08:45:13.687Z" + }, + "@bytelyst/react-auth": { + "version": "0.1.6", + "contentHash": "c4e4e86ed03b93ea6d1cb40e1a67315685cdb2a4e262858dfd29850a18a16a72", + "publishedAt": "2026-04-13T08:45:15.275Z" + }, + "@bytelyst/referral-client": { + "version": "0.1.5", + "contentHash": "d519fab34d2e41c54951f02e38e1ce7f513aa4f4610f52947737bafb2b52dfae", + "publishedAt": "2026-04-13T08:45:16.758Z" + }, + "@bytelyst/secure-storage-web": { + "version": "0.1.5", + "contentHash": "339d7122c0ec40bb1e84e99f74468b18cffde7600217fc7b0f91c89cf323f68c", + "publishedAt": "2026-04-13T08:45:18.264Z" + }, + "@bytelyst/speech": { + "version": "0.1.5", + "contentHash": "5dc93cd396b7a61d24ad28d5e27d9873cea9d9dd086b2ba51c644863a5134938", + "publishedAt": "2026-04-13T08:45:19.842Z" + }, + "@bytelyst/storage": { + "version": "0.1.5", + "contentHash": "65fb1ec119905bd862fb5ba1cc92cf88098067e162d4e8e058c565af9b7fae7b", + "publishedAt": "2026-04-13T08:45:21.411Z" + }, + "@bytelyst/subscription-client": { + "version": "0.1.5", + "contentHash": "881ff18db9b61f715b0b995720d5defdb2ad5d7b44e17aa0f2bfd4e8ad6729fa", + "publishedAt": "2026-04-13T08:45:23.046Z" + }, + "@bytelyst/survey-client": { + "version": "0.1.5", + "contentHash": "7d31d407924274dc4b1e4f6a06fce2b79b19f18e11270aa7a505a9bcefc2f8f9", + "publishedAt": "2026-04-13T08:45:24.602Z" + }, + "@bytelyst/sync": { + "version": "0.1.5", + "contentHash": "7bcc6c6e7df33f966a5c4ee240b31dba8a286dbcfdebaad3dfdcefdb0fccfc2c", + "publishedAt": "2026-04-13T08:45:26.173Z" + }, + "@bytelyst/telemetry-client": { + "version": "0.1.5", + "contentHash": "014acc903c05375e8decffcda698ba33a7993aed35916f48210546e8f4058138", + "publishedAt": "2026-04-13T08:45:27.699Z" + }, + "@bytelyst/testing": { + "version": "0.1.5", + "contentHash": "478bdf04d9b2c54f8778d9a6987ba63b6f4f728bb2c7fc8b138cf8d3e5035c20", + "publishedAt": "2026-04-13T08:45:29.298Z" + }, + "@bytelyst/time-references": { + "version": "0.1.5", + "contentHash": "70c04eeb491cf24ccb7cded95c4f213aff492c0f6b3b4d8be1af6395a266db59", + "publishedAt": "2026-04-13T08:45:30.916Z" + }, + "@bytelyst/ui": { + "version": "0.1.5", + "contentHash": "3ed0e0c895a9fc86a016330b82f13df2c2ced4957e144a1a64c7d8c6e28e2282", + "publishedAt": "2026-04-13T08:45:32.412Z" + }, + "@bytelyst/use-keyboard-shortcuts": { + "version": "0.1.6", + "contentHash": "04b917d4913f66247bfcfea53a871fac128e4b8d20bcdff6c2374e7f25aa8eee", + "publishedAt": "2026-04-13T08:45:33.972Z" + }, + "@bytelyst/use-theme": { + "version": "0.1.6", + "contentHash": "1767e51d2352224ee2ef36d40e6261afcf70bb643b984d0378874a35a458cc26", + "publishedAt": "2026-04-13T08:45:35.655Z" + }, + "@bytelyst/webhook-dispatch": { + "version": "0.1.5", + "contentHash": "e7afbed1158c657b1737716554cfc39f8d1263f03ee8c9774865e95622fadf8d", + "publishedAt": "2026-04-13T08:45:37.234Z" + } +} diff --git a/scripts/gitea/publish-outdated-packages.sh b/scripts/gitea/publish-outdated-packages.sh index 8787df94..01e3bcf6 100755 --- a/scripts/gitea/publish-outdated-packages.sh +++ b/scripts/gitea/publish-outdated-packages.sh @@ -2,25 +2,33 @@ set -euo pipefail # ───────────────────────────────────────────────────────────── -# Publish only OUTDATED @bytelyst/* packages to Gitea registry +# Publish OUTDATED @bytelyst/* packages to the Gitea npm registry. # -# Compares local built content against what's in the registry. -# Only publishes packages where the content has actually changed. +# Uses a local manifest (.publish-manifest.json) to track content hashes +# of the last-published version. Only packages whose built content has +# actually changed since the last publish are bumped and republished. +# +# Improvements over the previous version: +# - Manifest-based comparison (no registry tarball downloads) +# - Single pack per package (not double-pack) +# - Single metadata fetch per package (cached in-process) +# - No false-positive "OUTDATED" from pnpm-vs-npm pack differences +# - No .npmrc overwrite bug # # Usage: -# ./scripts/gitea/publish-outdated-packages.sh # detect + publish -# ./scripts/gitea/publish-outdated-packages.sh --dry-run # detect only -# ./scripts/gitea/publish-outdated-packages.sh --filter @bytelyst/errors +# scripts/gitea/publish-outdated-packages.sh # build + detect + publish +# scripts/gitea/publish-outdated-packages.sh --dry-run # build + detect only +# scripts/gitea/publish-outdated-packages.sh --skip-build # skip pnpm build +# scripts/gitea/publish-outdated-packages.sh --filter @bytelyst/errors # -# Requires: GITEA_NPM_TOKEN env var (or ~/.gitea_npm_token) +# Requires: GITEA_NPM_TOKEN (env var or ~/.gitea_npm_token) # ───────────────────────────────────────────────────────────── REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" PACKAGES_DIR="$REPO_ROOT/packages" +MANIFEST_FILE="$REPO_ROOT/scripts/gitea/.publish-manifest.json" # ── Network-aware Gitea resolution ───────────────────────── -# NETWORK=corp -> localhost:3300 (SSH tunnel to Azure VM) -# NETWORK=home -> Azure VM directly (gitea.bytelyst.com or ~/.gitea_vm_host) NETWORK_MODE="${NETWORK:-home}" if [ "$NETWORK_MODE" = "corp" ]; then @@ -29,7 +37,6 @@ if [ "$NETWORK_MODE" = "corp" ]; then GITEA_BASE="http://${GITEA_HOST}:${GITEA_PORT}" IS_CORP=true else - # Home network: use Azure VM host from ~/.gitea_vm_host or GITEA_NPM_HOST if [ -n "${GITEA_NPM_HOST:-}" ] && [ "${GITEA_NPM_HOST}" != "localhost" ]; then GITEA_HOST="$GITEA_NPM_HOST" elif [ -f "$HOME/.gitea_vm_host" ]; then @@ -44,7 +51,7 @@ fi REGISTRY_URL="${GITEA_NPM_REGISTRY_URL:-${GITEA_BASE}/api/packages/ByteLyst/npm/}" TOKEN="${GITEA_NPM_TOKEN:-}" -WORK_DIR="${TMPDIR:-/tmp}/bytelyst-outdated-check-$$" +WORK_DIR="${TMPDIR:-/tmp}/bytelyst-publish-$$" DRY_RUN=false PACKAGE_FILTER="" SKIP_BUILD=false @@ -67,35 +74,32 @@ while [[ $# -gt 0 ]]; do esac done -# Resolve token from file if not in env +# Resolve token if [ -z "$TOKEN" ] && [ -f "$HOME/.gitea_npm_token" ]; then TOKEN="$(cat "$HOME/.gitea_npm_token")" fi - if [ -z "$TOKEN" ]; then echo "ERROR: GITEA_NPM_TOKEN is required (env var or ~/.gitea_npm_token)" exit 1 fi -# Auth target for npm publish +# Auth target for .npmrc AUTH_TARGET="${REGISTRY_URL#http://}" AUTH_TARGET="${AUTH_TARGET#https://}" -# Skip non-npm packages (native SDKs) +# Non-npm packages to skip SKIP_DIRS="swift-platform-sdk swift-diagnostics kotlin-platform-sdk react-native-platform-sdk" -# Cleanup on exit +# Cleanup temp dir on exit trap 'rm -rf "$WORK_DIR"' EXIT mkdir -p "$WORK_DIR" -# Write .npmrc with auth token + scoped registry so npm publish bypasses publishConfig +# Single .npmrc for all npm operations (auth + scoped registry + proxy override) NPMRC_FILE="$WORK_DIR/.npmrc" { printf '//%s:_authToken=%s\n' "$AUTH_TARGET" "$TOKEN" - # Override publishConfig.registry in package.json (npm uses scoped registry first) printf '@bytelyst:registry=%s\n' "$REGISTRY_URL" if [ "$IS_CORP" = true ]; then - # Disable proxy for localhost (global ~/.npmrc has corp proxy) printf 'proxy=false\nhttps-proxy=false\n' fi } > "$NPMRC_FILE" @@ -103,184 +107,142 @@ NPMRC_FILE="$WORK_DIR/.npmrc" # ── Helpers ──────────────────────────────────────────────── pkg_field() { - node -e "process.stdout.write(JSON.parse(require('fs').readFileSync(process.argv[1],'utf8')).$1||'')" "$2" + node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'))['$1']||''))" "$2" } -# Compute a content fingerprint of all files under a directory. -# Sorts file paths, hashes each file, then hashes the combined result. -# This is metadata-independent (ignores tar headers, timestamps, etc.) -content_fingerprint() { - local dir="$1" - find "$dir" -type f -print0 | sort -z | xargs -0 shasum -a 256 | shasum -a 256 | cut -d' ' -f1 -} +# Compute a deterministic content hash from an extracted tarball. +# Normalizes package.json (version→0.0.0, strips publishConfig) so that +# version bumps alone don't trigger re-publish. +# Uses relative paths and stdin hashing to ensure determinism across runs. +content_hash() { + local extracted_dir="$1" # contains package/ subdirectory + local pkg_json="$extracted_dir/package/package.json" + local norm; norm=$(mktemp) -# Check if a package version exists in the registry. -# Gitea npm API: GET /{encoded_name} returns all versions. -registry_version_exists() { - local name="$1" version="$2" - local encoded_name="${name/@/%40}" - encoded_name="${encoded_name//\//%2F}" - local meta - meta=$(curl -s -H "Authorization: token $TOKEN" \ - "${REGISTRY_URL}${encoded_name}" 2>/dev/null) || return 1 - echo "$meta" | node -e " - let d='';process.stdin.on('data',c=>d+=c); - process.stdin.on('end',()=>{ - try{const p=JSON.parse(d);process.exit(p.versions&&p.versions['$version']?0:1)} - catch(e){process.exit(1)} - })" 2>/dev/null -} - -# Download a package tarball from the registry. -# Gitea npm API: GET /{encoded_name} → versions.{version}.dist.tarball -download_registry_tarball() { - local name="$1" version="$2" dest_dir="$3" - local encoded_name="${name/@/%40}" - encoded_name="${encoded_name//\//%2F}" - - # Fetch the full package metadata (all versions) - local meta - meta=$(curl -s -H "Authorization: token $TOKEN" \ - "${REGISTRY_URL}${encoded_name}" 2>/dev/null) || return 1 - - local tarball_url - tarball_url=$(echo "$meta" | node -e " - let d='';process.stdin.on('data',c=>d+=c); - process.stdin.on('end',()=>{ - try{ - const p=JSON.parse(d); - const v=p.versions&&p.versions['$version']; - if(!v||!v.dist||!v.dist.tarball){process.exit(1)} - process.stdout.write(v.dist.tarball) - }catch(e){process.exit(1)} - })" 2>/dev/null) || return 1 - - if [ -z "$tarball_url" ]; then - return 1 - fi - - curl -s -H "Authorization: token $TOKEN" \ - -o "$dest_dir/registry.tgz" \ - "$tarball_url" 2>/dev/null || return 1 - - [ -f "$dest_dir/registry.tgz" ] && [ -s "$dest_dir/registry.tgz" ] -} - -# Bump the patch version of a package.json (e.g., 0.1.0 → 0.1.1, 0.1.1 → 0.1.2). -# Also finds the next available version not yet in the registry. -bump_patch_version() { - local pkg_json="$1" pkg_name="$2" - local encoded_name="${pkg_name/@/%40}" - encoded_name="${encoded_name//\//%2F}" - - # Get all published versions from registry - local published_versions - published_versions=$(curl -s -H "Authorization: token $TOKEN" \ - "${REGISTRY_URL}${encoded_name}" 2>/dev/null | node -e " - let d='';process.stdin.on('data',c=>d+=c); - process.stdin.on('end',()=>{ - try{const p=JSON.parse(d);process.stdout.write(Object.keys(p.versions||{}).join(','))} - catch(e){process.stdout.write('')} - })" 2>/dev/null) || true - - # Compute next available patch version node -e " const fs=require('fs'); - const pkg=JSON.parse(fs.readFileSync(process.argv[1],'utf8')); - const published=new Set((process.argv[2]||'').split(',').filter(Boolean)); - const parts=pkg.version.split('.').map(Number); - // Start from current patch+1 and find first unpublished - parts[2]++; - while(published.has(parts.join('.'))){parts[2]++} - pkg.version=parts.join('.'); - fs.writeFileSync(process.argv[1],JSON.stringify(pkg,null,2)+'\n'); - process.stdout.write(pkg.version); - " "$pkg_json" "$published_versions" + const p=JSON.parse(fs.readFileSync(process.argv[1],'utf8')); + p.version='0.0.0'; delete p.publishConfig; + // Normalize @bytelyst/* dep versions (pnpm resolves workspace:* to exact versions + // which change on every bump — these shouldn't trigger re-publish) + for(const s of ['dependencies','devDependencies','peerDependencies']){ + if(!p[s])continue; + for(const [n]of Object.entries(p[s])){ + if(n.startsWith('@bytelyst/'))p[s][n]='*'; + } + } + fs.writeFileSync(process.argv[2],JSON.stringify(p)); + " "$pkg_json" "$norm" + + # Hash normalized package.json (via stdin — no path in output) + # + all other files using relative paths (cd into package/ first) + { + echo "PKG $(shasum -a 256 < "$norm" | cut -d' ' -f1)" + (cd "$extracted_dir/package" && find . -type f ! -name package.json -print0 \ + | sort -z | xargs -0 shasum -a 256 2>/dev/null) || true + } | shasum -a 256 | cut -d' ' -f1 + rm -f "$norm" } -# Publish a package using the same double-pack pattern as publish-local-packages.sh. -publish_package() { - local pkg_dir="$1" - local pkg_name pkg_version safe_name - pkg_name="$(pkg_field name "$pkg_dir/package.json")" - pkg_version="$(pkg_field version "$pkg_dir/package.json")" - safe_name="${pkg_name//@/}" - safe_name="${safe_name//\//-}" +# ── Manifest Operations ─────────────────────────────────── - local pub_dir="$WORK_DIR/publish-$safe_name" - rm -rf "$pub_dir" - mkdir -p "$pub_dir" - - # Step 1: pnpm pack - (cd "$pkg_dir" && pnpm pack --pack-destination "$pub_dir" >/dev/null 2>&1) - local packed_tgz - packed_tgz="$(find "$pub_dir" -maxdepth 1 -name '*.tgz' | head -1)" - if [ -z "$packed_tgz" ]; then - echo " ERROR: pnpm pack failed for $pkg_name" - return 1 - fi - - # Step 2: extract, strip publishConfig (so --registry wins), then npm repack - mkdir -p "$pub_dir/unpacked" - tar -xzf "$packed_tgz" -C "$pub_dir/unpacked" - rm -f "$packed_tgz" # remove pnpm tgz so only npm-repacked tgz remains +manifest_get_hash() { + local name="$1" + [ -f "$MANIFEST_FILE" ] || { echo ""; return; } node -e " - const fs=require('fs'),f=process.argv[1]; - const p=JSON.parse(fs.readFileSync(f,'utf8')); - delete p.publishConfig; - fs.writeFileSync(f,JSON.stringify(p,null,2)+'\n'); - " "$pub_dir/unpacked/package/package.json" - (cd "$pub_dir/unpacked/package" && npm pack --pack-destination "$pub_dir" >/dev/null 2>&1) + try{const m=JSON.parse(require('fs').readFileSync(process.argv[1],'utf8')); + process.stdout.write(m[process.argv[2]]?.contentHash||'')} + catch(e){process.stdout.write('')} + " "$MANIFEST_FILE" "$name" +} - local final_tgz - final_tgz="$(find "$pub_dir" -maxdepth 1 -name '*.tgz' | head -1)" - if [ -z "$final_tgz" ]; then - echo " ERROR: npm repack failed for $pkg_name" - return 1 - fi +manifest_set() { + local name="$1" version="$2" hash="$3" + node -e " + const fs=require('fs'); + let m={};try{m=JSON.parse(fs.readFileSync(process.argv[1],'utf8'))}catch(e){} + m[process.argv[2]]={version:process.argv[3],contentHash:process.argv[4], + publishedAt:new Date().toISOString()}; + const s=Object.fromEntries(Object.entries(m).sort(([a],[b])=>a.localeCompare(b))); + fs.writeFileSync(process.argv[1],JSON.stringify(s,null,2)+'\n'); + " "$MANIFEST_FILE" "$name" "$version" "$hash" +} - # Step 3: publish to Gitea registry. - # Run from WORK_DIR (in /tmp with .npmrc for auth) so npm won't find - # the repo's .npmrc which has @bytelyst:registry pointing externally. - # Publish using shared .npmrc (has auth, scoped registry, and proxy=false on corp) - # Strip all proxy/registry env vars so only .npmrc settings apply - if ! (cd "$WORK_DIR" && env \ +# ── Registry Helpers (single fetch, cached) ─────────────── + +# Cache file: one line per package = "name:ver1,ver2,ver3" +REGISTRY_CACHE_FILE="$WORK_DIR/.registry-cache" +: > "$REGISTRY_CACHE_FILE" + +registry_versions() { + local name="$1" + # Check cache first + local cached + cached=$(grep "^${name}:" "$REGISTRY_CACHE_FILE" 2>/dev/null | cut -d: -f2-) || true + if [ -n "$cached" ]; then echo "$cached"; return; fi + + local encoded="${name/@/%40}"; encoded="${encoded//\//%2F}" + local versions + versions=$(curl -s -H "Authorization: token $TOKEN" \ + "${REGISTRY_URL}${encoded}" 2>/dev/null \ + | node -e "let d='';process.stdin.on('data',c=>d+=c); + process.stdin.on('end',()=>{try{ + process.stdout.write(Object.keys(JSON.parse(d).versions||{}).join(',')) + }catch(e){process.stdout.write('')}})" 2>/dev/null) || true + echo "${name}:${versions}" >> "$REGISTRY_CACHE_FILE" + echo "$versions" +} + +next_version() { + local name="$1" current="$2" + local versions; versions=$(registry_versions "$name") + node -e " + const pub=new Set((process.argv[1]||'').split(',').filter(Boolean)); + const p=process.argv[2].split('.').map(Number); + p[2]++;while(pub.has(p.join('.'))){p[2]++} + process.stdout.write(p.join('.')); + " "$versions" "$current" +} + +version_exists() { + local name="$1" version="$2" + local versions; versions=$(registry_versions "$name") + echo ",$versions," | grep -q ",$version," +} + +# Run npm commands with proxy/env stripping for reliable localhost access +npm_clean() { + (cd "$WORK_DIR" && env \ -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \ -u npm_config_proxy -u npm_config_https_proxy \ -u NPM_CONFIG_PROXY -u NPM_CONFIG_HTTPS_PROXY \ -u NPM_CONFIG_REGISTRY -u NPM_CONFIG_STRICT_SSL \ - -u NPM_CONFIG_NOPROXY \ - -u NODE_TLS_REJECT_UNAUTHORIZED \ - npm publish "$final_tgz" \ - --registry "$REGISTRY_URL" \ - --userconfig "$NPMRC_FILE" 2>&1); then - echo " ERROR: publish failed for $pkg_name@$pkg_version" - return 1 - fi + -u NPM_CONFIG_NOPROXY -u NODE_TLS_REJECT_UNAUTHORIZED \ + "$@") } # ── Main ─────────────────────────────────────────────────── -# Show resolved config echo "==> Network: $NETWORK_MODE ($( [ "$IS_CORP" = true ] && echo "corp — localhost tunnel" || echo "home — Azure VM" ))" echo " Registry: $REGISTRY_URL" echo "" -# Step 1: Build all packages +# Phase 1: Build if [ "$SKIP_BUILD" = false ]; then echo "==> Building all packages..." (cd "$REPO_ROOT" && pnpm build 2>&1 | tail -5) echo "" fi -# Step 2: Check each package -echo "==> Checking packages against registry..." +# Phase 2: Check each package against manifest +echo "==> Checking packages (manifest-based)..." echo "" +# Arrays for tracking results outdated_dirs=() outdated_names=() +outdated_hashes=() # content hash per outdated package (for manifest update after publish) up_to_date=0 -not_found=0 changed=0 skipped=0 errors=0 @@ -291,76 +253,66 @@ for pkg_json in "$PACKAGES_DIR"/*/package.json; do # Skip native SDKs if echo "$SKIP_DIRS" | grep -qw "$dir_name"; then - ((skipped++)) - continue + ((skipped++)); continue fi pkg_name="$(pkg_field name "$pkg_json")" pkg_version="$(pkg_field version "$pkg_json")" + # Skip private packages + private_flag="$(pkg_field private "$pkg_json")" + if [ "$private_flag" = "true" ]; then + ((skipped++)); continue + fi + # Apply filter if [ -n "$PACKAGE_FILTER" ] && [ "$pkg_name" != "$PACKAGE_FILTER" ]; then continue fi - # Check if dist/ exists (package must be built) + # Must have built output if [ ! -d "$pkg_dir/dist" ] && [ ! -d "$pkg_dir/generated" ]; then echo " SKIP (no dist/): $pkg_name" - ((skipped++)) - continue + ((skipped++)); continue fi - # Prepare work dirs - local_work="$WORK_DIR/check-$dir_name/local" - registry_work="$WORK_DIR/check-$dir_name/registry" - rm -rf "$WORK_DIR/check-$dir_name" - mkdir -p "$local_work" "$registry_work" + # Pack locally (single pack — reused for publish if needed) + safe_name="${pkg_name//@/}"; safe_name="${safe_name//\//-}" + pack_dir="$WORK_DIR/$safe_name" + rm -rf "$pack_dir"; mkdir -p "$pack_dir/extracted" - # Pack locally - if ! (cd "$pkg_dir" && pnpm pack --pack-destination "$local_work" >/dev/null 2>&1); then - echo " ERROR (pack failed): $pkg_name" - ((errors++)) - continue + if ! (cd "$pkg_dir" && pnpm pack --pack-destination "$pack_dir" >/dev/null 2>&1); then + echo " ERROR (pack): $pkg_name" + ((errors++)); continue fi - local_tgz="$(find "$local_work" -maxdepth 1 -name '*.tgz' | head -1)" + local_tgz="$(find "$pack_dir" -maxdepth 1 -name '*.tgz' | head -1)" if [ -z "$local_tgz" ]; then echo " ERROR (no tgz): $pkg_name" - ((errors++)) - continue + ((errors++)); continue fi - # Extract local tarball - mkdir -p "$local_work/extracted" - tar xzf "$local_tgz" -C "$local_work/extracted" 2>/dev/null + # Extract for content hashing (keep around for publish) + tar xzf "$local_tgz" -C "$pack_dir/extracted" 2>/dev/null - # Try to download registry tarball - if download_registry_tarball "$pkg_name" "$pkg_version" "$registry_work"; then - # Extract registry tarball - mkdir -p "$registry_work/extracted" - tar xzf "$registry_work/registry.tgz" -C "$registry_work/extracted" 2>/dev/null + # Compute content hash + local_hash="$(content_hash "$pack_dir/extracted")" + manifest_hash="$(manifest_get_hash "$pkg_name")" - # Compare content fingerprints - local_fp="$(content_fingerprint "$local_work/extracted")" - registry_fp="$(content_fingerprint "$registry_work/extracted")" - - if [ "$local_fp" = "$registry_fp" ]; then - echo " UP-TO-DATE: $pkg_name@$pkg_version" - ((up_to_date++)) - else - echo " OUTDATED: $pkg_name@$pkg_version" - outdated_dirs+=("$pkg_dir") - outdated_names+=("$pkg_name@$pkg_version") - ((changed++)) - fi + if [ "$local_hash" = "$manifest_hash" ]; then + echo " UP-TO-DATE: $pkg_name@$pkg_version" + ((up_to_date++)) + rm -rf "$pack_dir" # free disk else - echo " NOT FOUND: $pkg_name@$pkg_version (will publish)" + if [ -z "$manifest_hash" ]; then + echo " NEW: $pkg_name@$pkg_version" + else + echo " CHANGED: $pkg_name@$pkg_version" + fi outdated_dirs+=("$pkg_dir") - outdated_names+=("$pkg_name@$pkg_version") - ((not_found++)) + outdated_names+=("$pkg_name") + outdated_hashes+=("$local_hash") + ((changed++)) fi - - # Cleanup check dir to save disk space - rm -rf "$WORK_DIR/check-$dir_name" done # ── Summary ──────────────────────────────────────────────── @@ -368,8 +320,7 @@ done echo "" echo "==> Summary" echo " Up-to-date: $up_to_date" -echo " Outdated: $changed" -echo " Not found: $not_found" +echo " Changed: $changed" echo " Skipped: $skipped" echo " Errors: $errors" echo "" @@ -390,59 +341,97 @@ if [ "$DRY_RUN" = true ]; then exit 0 fi -# Step 3: Publish outdated packages +# Phase 3: Publish changed packages echo "==> Publishing ${#outdated_dirs[@]} package(s)..." echo "" -# Write .npmrc into WORK_DIR for auth (npm reads .npmrc from cwd) -cat > "$WORK_DIR/.npmrc" </dev/null 2>&1); then + echo " ERROR: npm repack failed" + ((pub_errors++)); continue + fi + + final_tgz="$(find "$pack_dir" -maxdepth 1 -name '*.tgz' | head -1)" + if [ -z "$final_tgz" ]; then + echo " ERROR: no tarball after repack" + ((pub_errors++)); continue + fi # Publish echo " Publishing $pkg_name@$pkg_version..." - if publish_package "$pkg_dir"; then + if npm_clean npm publish "$final_tgz" \ + --registry "$REGISTRY_URL" \ + --userconfig "$NPMRC_FILE" 2>&1; then echo " Published $pkg_name@$pkg_version" + manifest_set "$pkg_name" "$pkg_version" "$local_hash" ((published++)) else echo " FAILED to publish $pkg_name@$pkg_version" ((pub_errors++)) fi + + # Free disk + rm -rf "$pack_dir" echo "" done echo "==> Done: $published published, $pub_errors failed" -# Show bumped packages so the user knows which package.json files changed if [ ${#bumped_packages[@]} -gt 0 ]; then echo "" - echo "NOTE: ${#bumped_packages[@]} package(s) had their patch version bumped." - echo " These package.json changes are local — commit them when ready:" - for d in "${bumped_packages[@]}"; do - echo " $d/package.json" + echo "NOTE: ${#bumped_packages[@]} package(s) had their version bumped." + echo " Commit these + the manifest when ready:" + for f in "${bumped_packages[@]}"; do + echo " $f" done + echo " $MANIFEST_FILE" fi exit $((pub_errors > 0 ? 1 : 0)) diff --git a/scripts/gitea/release-packages.sh b/scripts/gitea/release-packages.sh index 86a5a47d..c07add36 100755 --- a/scripts/gitea/release-packages.sh +++ b/scripts/gitea/release-packages.sh @@ -97,14 +97,20 @@ is_skip_package() { return 1 } -# Check registry using shared npmrc (reliable auth for both GET and PUT) +# Check registry using shared npmrc (reliable auth, proxy stripped) version_on_registry() { local name="$1" version="$2" - npm view "${name}@${version}" version \ + (cd "$TMP_DIR" && env \ + -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \ + -u npm_config_proxy -u npm_config_https_proxy \ + -u NPM_CONFIG_PROXY -u NPM_CONFIG_HTTPS_PROXY \ + -u NPM_CONFIG_REGISTRY -u NPM_CONFIG_STRICT_SSL \ + -u NPM_CONFIG_NOPROXY -u NODE_TLS_REJECT_UNAUTHORIZED \ + npm view "${name}@${version}" version \ --registry "$REGISTRY_URL" \ --userconfig "$NPMRC_FILE" \ --silent \ - 2>/dev/null || true + 2>/dev/null) || true } # ── Preflight ────────────────────────────────────────────────────────────────── @@ -123,7 +129,13 @@ command -v node >/dev/null 2>&1 || fail "node not found in PATH" # Create shared tmp dir + npmrc early so version checks work before publishing mkdir -p "$TMP_DIR" trap 'rm -rf "$TMP_DIR"' EXIT -printf '//%s:_authToken=%s\n' "$AUTH_TARGET" "$TOKEN" > "$NPMRC_FILE" +{ + printf '//%s:_authToken=%s\n' "$AUTH_TARGET" "$TOKEN" + printf '@bytelyst:registry=%s\n' "$REGISTRY_URL" + if [ "$IS_CORP" = true ]; then + printf 'proxy=false\nhttps-proxy=false\n' + fi +} > "$NPMRC_FILE" # Show resolved config log "Network: $NETWORK_MODE ($( [ "$IS_CORP" = true ] && echo "corp — localhost tunnel" || echo "home — Azure VM" ))" @@ -131,11 +143,17 @@ info "Registry: $REGISTRY_URL" # Verify token can read from registry log "Verifying registry credentials..." -if ! npm view "@bytelyst/errors" version \ +if ! (cd "$TMP_DIR" && env \ + -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \ + -u npm_config_proxy -u npm_config_https_proxy \ + -u NPM_CONFIG_PROXY -u NPM_CONFIG_HTTPS_PROXY \ + -u NPM_CONFIG_REGISTRY -u NPM_CONFIG_STRICT_SSL \ + -u NPM_CONFIG_NOPROXY -u NODE_TLS_REJECT_UNAUTHORIZED \ + npm view "@bytelyst/errors" version \ --registry "$REGISTRY_URL" \ --userconfig "$NPMRC_FILE" \ - --silent 2>/dev/null; then - fail "Registry auth failed — check GITEA_NPM_TOKEN has read:package scope" + --silent 2>/dev/null); then + fail "Registry auth failed — check GITEA_NPM_TOKEN has read+write:package scope" fi ok "Registry credentials verified" @@ -324,30 +342,20 @@ publish_package() { return fi - # Publish using shared npmrc (corp: strip proxy env so npm reaches localhost directly) + # Publish using shared npmrc (strip proxy env so npm reaches localhost/VM directly) local publish_log="$work_dir/publish.log" local publish_ok=false - if [ "$IS_CORP" = true ]; then - if (cd "$work_dir" && env \ - -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \ - -u npm_config_proxy -u npm_config_https_proxy \ - -u NPM_CONFIG_PROXY -u NPM_CONFIG_HTTPS_PROXY \ - -u npm_config_noproxy -u NPM_CONFIG_NOPROXY \ - -u NODE_TLS_REJECT_UNAUTHORIZED \ - npm publish "$final_tgz" \ - --registry "$REGISTRY_URL" \ - --userconfig "$NPMRC_FILE" \ - --silent 2>"$publish_log"); then - publish_ok=true - fi - else - if npm publish "$final_tgz" \ - --registry "$REGISTRY_URL" \ - --userconfig "$NPMRC_FILE" \ - --silent \ - 2>"$publish_log"; then - publish_ok=true - fi + if (cd "$TMP_DIR" && env \ + -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \ + -u npm_config_proxy -u npm_config_https_proxy \ + -u NPM_CONFIG_PROXY -u NPM_CONFIG_HTTPS_PROXY \ + -u NPM_CONFIG_REGISTRY -u NPM_CONFIG_STRICT_SSL \ + -u NPM_CONFIG_NOPROXY -u NODE_TLS_REJECT_UNAUTHORIZED \ + npm publish "$final_tgz" \ + --registry "$REGISTRY_URL" \ + --userconfig "$NPMRC_FILE" \ + --silent 2>"$publish_log"); then + publish_ok=true fi if [ "$publish_ok" = true ]; then ok " ✅ $name@$version published"