Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place

dockerfile work

nekomimi.pet 75f9efeb ec6efeba

verified
Changed files
+104 -67
apps
hosting-service
main-app
public
editor
tabs
src
routes
binaries
docs
src
content
docs
packages
@wisp
fs-utils
+9 -11
Dockerfile
··· 4 4 # Set working directory 5 5 WORKDIR /app 6 6 7 - # Copy package files 8 - COPY package.json ./ 7 + # Copy workspace configuration 8 + COPY package.json bunfig.toml tsconfig.json ./ 9 9 10 - # Copy Bun configuration 11 - COPY bunfig.toml ./ 10 + # Copy workspace packages 11 + COPY packages ./packages 12 12 13 - COPY tsconfig.json ./ 13 + # Copy both apps (needed for workspace resolution) 14 + COPY apps/main-app ./apps/main-app 15 + COPY apps/hosting-service/package.json ./apps/hosting-service/package.json 14 16 15 - # Install dependencies 17 + # Install all dependencies (including workspaces) 16 18 RUN bun install 17 19 18 - # Copy source code 19 - COPY src ./src 20 - COPY public ./public 21 - 22 20 ENV PORT=8000 23 21 ENV NODE_ENV=production 24 22 25 23 EXPOSE 8000 26 24 27 - CMD ["bun", "start"] 25 + CMD ["bun", "run", "start"]
+20 -9
apps/hosting-service/Dockerfile
··· 1 - # Use official Node.js Alpine image 1 + # Use official Node.js Alpine image with pnpm 2 + # Build from monorepo root: docker build -f apps/hosting-service/Dockerfile . 2 3 FROM node:alpine AS base 3 4 5 + # Install pnpm globally (supports workspace: protocol) 6 + RUN npm install -g pnpm 7 + 4 8 # Set working directory 5 9 WORKDIR /app 6 10 7 - # Copy package files 8 - COPY package.json ./ 11 + # Copy workspace configuration 12 + COPY package.json tsconfig.json ./ 13 + 14 + # Copy all workspace packages 15 + COPY packages ./packages 16 + 17 + # Copy hosting-service and main-app package.json (for workspace resolution) 18 + COPY apps/hosting-service ./apps/hosting-service 19 + COPY apps/main-app/package.json ./apps/main-app/package.json 9 20 10 - # Install dependencies 11 - RUN npm install 21 + # Install all dependencies (including workspaces) 22 + RUN pnpm install --frozen-lockfile || pnpm install 12 23 13 - # Copy source code 14 - COPY src ./src 24 + # Set working directory to hosting-service 25 + WORKDIR /app/apps/hosting-service 15 26 16 27 # Create cache directory 17 28 RUN mkdir -p ./cache/sites ··· 27 38 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ 28 39 CMD node -e "fetch('http://localhost:3001/health').then(r => r.ok ? process.exit(0) : process.exit(1)).catch(() => process.exit(1))" 29 40 30 - # Start the application (can override with 'npm run backfill' in compose) 31 - CMD ["npm", "run", "start"] 41 + # Start the application (can override with 'pnpm run backfill' in compose) 42 + CMD ["pnpm", "run", "start"]
+4 -3
apps/hosting-service/src/lib/firehose.ts
··· 6 6 } from './utils' 7 7 import { upsertSite, tryAcquireLock, releaseLock } from './db' 8 8 import { safeFetch } from '@wisp/safe-fetch' 9 - import { isRecord, validateRecord } from '@wisp/lexicons/types/place/wisp/fs' 9 + // import { isRecord, validateRecord } from '@wisp/lexicons/types/place/wisp/fs' 10 + import { isRecord } from '@wisp/lexicons/types/place/wisp/fs' 10 11 import { Firehose } from '@atproto/sync' 11 12 import { IdResolver } from '@atproto/identity' 12 13 import { invalidateSiteCache, markSiteAsBeingCached, unmarkSiteAsBeingCached } from './cache' ··· 65 66 // If the write is a valid place.wisp.fs record 66 67 if ( 67 68 evt.collection === 'place.wisp.fs' && 68 - isRecord(record) && 69 - validateRecord(record).success 69 + isRecord(record) 70 + // && validateRecord(record).success 70 71 ) { 71 72 this.log('Received place.wisp.fs event', { 72 73 did: evt.did,
+4 -2
apps/main-app/package.json
··· 17 17 "@wisp/database": "workspace:*", 18 18 "@wisp/fs-utils": "workspace:*", 19 19 "@atproto/api": "^0.17.3", 20 + "@atproto/common-web": "^0.4.5", 21 + "@atproto/jwk-jose": "^0.1.11", 20 22 "@atproto/lex-cli": "^0.9.5", 21 23 "@atproto/oauth-client-node": "^0.3.9", 22 24 "@atproto/xrpc-server": "^0.9.5", ··· 47 49 "tailwindcss": "4", 48 50 "tw-animate-css": "^1.4.0", 49 51 "typescript": "^5.9.3", 50 - "zlib": "^1.0.5" 52 + "zlib": "^1.0.5", 53 + "bun-plugin-tailwind": "^0.1.2" 51 54 }, 52 55 "devDependencies": { 53 56 "@types/react": "^19.2.2", 54 57 "@types/react-dom": "^19.2.1", 55 - "bun-plugin-tailwind": "^0.1.2", 56 58 "bun-types": "latest", 57 59 "esbuild": "0.26.0", 58 60 "playwright": "^1.49.0"
+12 -2
apps/main-app/public/editor/tabs/CLITab.tsx
··· 17 17 <div className="flex items-center gap-2 mb-2"> 18 18 <CardTitle>Wisp CLI Tool</CardTitle> 19 19 <Badge variant="secondary" className="text-xs"> 20 - v0.2.0 20 + v0.4.0 21 21 </Badge> 22 22 <Badge variant="outline" className="text-xs"> 23 23 Alpha ··· 55 55 </div> 56 56 57 57 <div className="space-y-3"> 58 - <h3 className="text-sm font-semibold">Download v0.2.0</h3> 58 + <h3 className="text-sm font-semibold">Download v0.4.0</h3> 59 59 <div className="grid gap-2"> 60 60 <div className="p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border"> 61 61 <a ··· 183 183 wisp-cli serve your-handle.bsky.social \\ 184 184 --site my-site \\ 185 185 --port 3000 186 + 187 + # Enable SPA mode (serve index.html for all routes) 188 + wisp-cli serve your-handle.bsky.social \\ 189 + --site my-site \\ 190 + --spa 191 + 192 + # Enable directory listing for paths without index files 193 + wisp-cli serve your-handle.bsky.social \\ 194 + --site my-site \\ 195 + --directory 186 196 187 197 # Downloads site, serves it, and watches firehose for live updates!`} 188 198 language="bash"
+19 -18
apps/main-app/src/routes/wisp.ts
··· 22 22 import { createManifest } from '@wisp/fs-utils' 23 23 import { upsertSite } from '../lib/db' 24 24 import { createLogger } from '@wisp/observability' 25 - import { validateRecord, type Directory } from '@wisp/lexicons/types/place/wisp/fs' 26 - import { validateRecord as validateSubfsRecord } from '@wisp/lexicons/types/place/wisp/subfs' 25 + // import { validateRecord, type Directory } from '@wisp/lexicons/types/place/wisp/fs' 26 + import { type Directory } from '@wisp/lexicons/types/place/wisp/fs' 27 + // import { validateRecord as validateSubfsRecord } from '@wisp/lexicons/types/place/wisp/subfs' 27 28 import { MAX_SITE_SIZE, MAX_FILE_SIZE, MAX_FILE_COUNT } from '@wisp/constants' 28 29 import { 29 30 createUploadJob, ··· 373 374 createdAt: new Date().toISOString() 374 375 }; 375 376 376 - const validationResult = validateRecord(emptyManifest); 377 - if (!validationResult.success) { 378 - throw new Error(`Invalid manifest: ${validationResult.error?.message || 'Validation failed'}`); 379 - } 377 + // const validationResult = validateRecord(emptyManifest); 378 + // if (!validationResult.success) { 379 + // throw new Error(`Invalid manifest: ${validationResult.error?.message || 'Validation failed'}`); 380 + // } 380 381 381 382 const rkey = siteName; 382 383 updateJobProgress(jobId, { phase: 'finalizing' }); ··· 735 736 }; 736 737 737 738 // Validate subfs record 738 - const subfsValidation = validateSubfsRecord(subfsManifest); 739 - if (!subfsValidation.success) { 740 - throw new Error(`Invalid subfs manifest: ${subfsValidation.error?.message || 'Validation failed'}`); 741 - } 739 + // const subfsValidation = validateSubfsRecord(subfsManifest); 740 + // if (!subfsValidation.success) { 741 + // throw new Error(`Invalid subfs manifest: ${subfsValidation.error?.message || 'Validation failed'}`); 742 + // } 742 743 743 744 // Upload subfs record to PDS 744 745 const subfsRecord = await agent.com.atproto.repo.putRecord({ ··· 789 790 }; 790 791 791 792 // Validate subfs record 792 - const subfsValidation = validateSubfsRecord(subfsManifest); 793 - if (!subfsValidation.success) { 794 - throw new Error(`Invalid subfs manifest: ${subfsValidation.error?.message || 'Validation failed'}`); 795 - } 793 + // const subfsValidation = validateSubfsRecord(subfsManifest); 794 + // if (!subfsValidation.success) { 795 + // throw new Error(`Invalid subfs manifest: ${subfsValidation.error?.message || 'Validation failed'}`); 796 + // } 796 797 797 798 // Upload subfs record to PDS 798 799 const subfsRecord = await agent.com.atproto.repo.putRecord({ ··· 1070 1071 createdAt: new Date().toISOString() 1071 1072 }; 1072 1073 1073 - const validationResult = validateRecord(emptyManifest); 1074 - if (!validationResult.success) { 1075 - throw new Error(`Invalid manifest: ${validationResult.error?.message || 'Validation failed'}`); 1076 - } 1074 + // const validationResult = validateRecord(emptyManifest); 1075 + // if (!validationResult.success) { 1076 + // throw new Error(`Invalid manifest: ${validationResult.error?.message || 'Validation failed'}`); 1077 + // } 1077 1078 1078 1079 const rkey = siteName; 1079 1080
+1 -1
binaries/index.html
··· 234 234 </head> 235 235 <body> 236 236 <div class="container"> 237 - <h1>Wisp CLI <span style="font-size: 1.5rem; color: var(--demo-text-secondary);">v0.2.0</span></h1> 237 + <h1>Wisp CLI <span style="font-size: 1.5rem; color: var(--demo-text-secondary);">v0.4.0</span></h1> 238 238 <p class="subtitle">Deploy static sites to the AT Protocol</p> 239 239 240 240 <div class="description">
+24 -14
bun.lock
··· 4 4 "workspaces": { 5 5 "": { 6 6 "name": "elysia-static", 7 + "dependencies": { 8 + "bun-plugin-tailwind": "^0.1.2", 9 + "tailwindcss": "4", 10 + }, 7 11 }, 8 12 "apps/hosting-service": { 9 13 "name": "wisp-hosting-service", ··· 39 43 "version": "1.0.50", 40 44 "dependencies": { 41 45 "@atproto/api": "^0.17.3", 46 + "@atproto/common-web": "^0.4.5", 47 + "@atproto/jwk-jose": "^0.1.11", 42 48 "@atproto/lex-cli": "^0.9.5", 43 49 "@atproto/oauth-client-node": "^0.3.9", 44 50 "@atproto/xrpc-server": "^0.9.5", ··· 62 68 "@wisp/observability": "workspace:*", 63 69 "actor-typeahead": "^0.1.1", 64 70 "atproto-ui": "^0.11.3", 71 + "bun-plugin-tailwind": "^0.1.2", 65 72 "class-variance-authority": "^0.7.1", 66 73 "clsx": "^2.1.1", 67 74 "elysia": "latest", ··· 80 87 "devDependencies": { 81 88 "@types/react": "^19.2.2", 82 89 "@types/react-dom": "^19.2.1", 83 - "bun-plugin-tailwind": "^0.1.2", 84 90 "bun-types": "latest", 85 91 "esbuild": "0.26.0", 86 92 "playwright": "^1.49.0", ··· 191 197 192 198 "@atproto/common": ["@atproto/common@0.4.12", "", { "dependencies": { "@atproto/common-web": "^0.4.3", "@ipld/dag-cbor": "^7.0.3", "cbor-x": "^1.5.1", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "pino": "^8.21.0" } }, "sha512-NC+TULLQiqs6MvNymhQS5WDms3SlbIKGLf4n33tpftRJcalh507rI+snbcUb7TLIkKw7VO17qMqxEXtIdd5auQ=="], 193 199 194 - "@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 200 + "@atproto/common-web": ["@atproto/common-web@0.4.5", "", { "dependencies": { "@atproto/lex-data": "0.0.1", "@atproto/lex-json": "0.0.1", "zod": "^3.23.8" } }, "sha512-Tx0xUafLm3vRvOQpbBl5eb9V8xlC7TaRXs6dAulHRkDG3Kb+P9qn3pkDteq+aeMshbVXbVa1rm3Ok4vFyuoyYA=="], 195 201 196 202 "@atproto/crypto": ["@atproto/crypto@0.4.4", "", { "dependencies": { "@noble/curves": "^1.7.0", "@noble/hashes": "^1.6.1", "uint8arrays": "3.0.0" } }, "sha512-Yq9+crJ7WQl7sxStVpHgie5Z51R05etaK9DLWYG/7bR5T4bhdcIgF6IfklLShtZwLYdVVj+K15s0BqW9a8PSDA=="], 197 203 ··· 939 945 940 946 "@atproto-labs/fetch-node/ipaddr.js": ["ipaddr.js@2.2.0", "", {}, "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA=="], 941 947 948 + "@atproto/api/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 949 + 942 950 "@atproto/api/@atproto/lexicon": ["@atproto/lexicon@0.4.14", "", { "dependencies": { "@atproto/common-web": "^0.4.2", "@atproto/syntax": "^0.4.0", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-jiKpmH1QER3Gvc7JVY5brwrfo+etFoe57tKPQX/SmPwjvUsFnJAow5xLIryuBaJgFAhnTZViXKs41t//pahGHQ=="], 943 951 944 952 "@atproto/api/@atproto/xrpc": ["@atproto/xrpc@0.6.12", "", { "dependencies": { "@atproto/lexicon": "^0.4.10", "zod": "^3.23.8" } }, "sha512-Ut3iISNLujlmY9Gu8sNU+SPDJDvqlVzWddU8qUr0Yae5oD4SguaUFjjhireMGhQ3M5E0KljQgDbTmnBo1kIZ3w=="], 945 953 946 954 "@atproto/api/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 947 955 948 - "@atproto/common/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 949 - 950 - "@atproto/common-web/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 956 + "@atproto/common/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 951 957 952 - "@atproto/identity/@atproto/common-web": ["@atproto/common-web@0.4.5", "", { "dependencies": { "@atproto/lex-data": "0.0.1", "@atproto/lex-json": "0.0.1", "zod": "^3.23.8" } }, "sha512-Tx0xUafLm3vRvOQpbBl5eb9V8xlC7TaRXs6dAulHRkDG3Kb+P9qn3pkDteq+aeMshbVXbVa1rm3Ok4vFyuoyYA=="], 958 + "@atproto/common/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 953 959 954 960 "@atproto/jwk/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 955 961 ··· 959 965 960 966 "@atproto/lex-data/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 961 967 962 - "@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.5", "", { "dependencies": { "@atproto/lex-data": "0.0.1", "@atproto/lex-json": "0.0.1", "zod": "^3.23.8" } }, "sha512-Tx0xUafLm3vRvOQpbBl5eb9V8xlC7TaRXs6dAulHRkDG3Kb+P9qn3pkDteq+aeMshbVXbVa1rm3Ok4vFyuoyYA=="], 963 - 964 968 "@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 965 969 966 970 "@atproto/oauth-client/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 967 971 968 972 "@atproto/repo/@atproto/common": ["@atproto/common@0.5.1", "", { "dependencies": { "@atproto/common-web": "^0.4.5", "@atproto/lex-cbor": "0.0.1", "@atproto/lex-data": "0.0.1", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "pino": "^8.21.0" } }, "sha512-0S57sjzw4r9OLc5srJFi6uAz/aTKYl6btz3x36tSnGriL716m6h0x2IVtgd+FhUfIQfisevrqcqw8SfaGk8VTw=="], 969 - 970 - "@atproto/repo/@atproto/common-web": ["@atproto/common-web@0.4.5", "", { "dependencies": { "@atproto/lex-data": "0.0.1", "@atproto/lex-json": "0.0.1", "zod": "^3.23.8" } }, "sha512-Tx0xUafLm3vRvOQpbBl5eb9V8xlC7TaRXs6dAulHRkDG3Kb+P9qn3pkDteq+aeMshbVXbVa1rm3Ok4vFyuoyYA=="], 971 973 972 974 "@atproto/repo/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 973 975 ··· 1021 1023 1022 1024 "wisp-hosting-service/@atproto/lexicon": ["@atproto/lexicon@0.5.1", "", { "dependencies": { "@atproto/common-web": "^0.4.3", "@atproto/syntax": "^0.4.1", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-y8AEtYmfgVl4fqFxqXAeGvhesiGkxiy3CWoJIfsFDDdTlZUC8DFnZrYhcqkIop3OlCkkljvpSJi1hbeC1tbi8A=="], 1023 1025 1024 - "@atproto/lex-cli/@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 1026 + "@atproto/lex-cli/@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 1025 1027 1026 - "@atproto/sync/@atproto/common/@atproto/common-web": ["@atproto/common-web@0.4.5", "", { "dependencies": { "@atproto/lex-data": "0.0.1", "@atproto/lex-json": "0.0.1", "zod": "^3.23.8" } }, "sha512-Tx0xUafLm3vRvOQpbBl5eb9V8xlC7TaRXs6dAulHRkDG3Kb+P9qn3pkDteq+aeMshbVXbVa1rm3Ok4vFyuoyYA=="], 1028 + "@atproto/lex-cli/@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 1027 1029 1028 1030 "@atproto/sync/@atproto/xrpc-server/@atproto/xrpc": ["@atproto/xrpc@0.7.6", "", { "dependencies": { "@atproto/lexicon": "^0.5.2", "zod": "^3.23.8" } }, "sha512-RvCf4j0JnKYWuz3QzsYCntJi3VuiAAybQsMIUw2wLWcHhchO9F7UaBZINLL2z0qc/cYWPv5NSwcVydMseoCZLA=="], 1029 1031 1030 - "@atproto/ws-client/@atproto/common/@atproto/common-web": ["@atproto/common-web@0.4.5", "", { "dependencies": { "@atproto/lex-data": "0.0.1", "@atproto/lex-json": "0.0.1", "zod": "^3.23.8" } }, "sha512-Tx0xUafLm3vRvOQpbBl5eb9V8xlC7TaRXs6dAulHRkDG3Kb+P9qn3pkDteq+aeMshbVXbVa1rm3Ok4vFyuoyYA=="], 1031 - 1032 1032 "@atproto/ws-client/@atproto/common/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 1033 1033 1034 + "@atproto/xrpc-server/@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 1035 + 1034 1036 "@atproto/xrpc-server/@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 1037 + 1038 + "@atproto/xrpc/@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 1035 1039 1036 1040 "@atproto/xrpc/@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 1037 1041 1038 1042 "@tokenizer/inflate/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], 1043 + 1044 + "@wisp/main-app/@atproto/api/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 1039 1045 1040 1046 "@wisp/main-app/@atproto/api/@atproto/lexicon": ["@atproto/lexicon@0.5.1", "", { "dependencies": { "@atproto/common-web": "^0.4.3", "@atproto/syntax": "^0.4.1", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-y8AEtYmfgVl4fqFxqXAeGvhesiGkxiy3CWoJIfsFDDdTlZUC8DFnZrYhcqkIop3OlCkkljvpSJi1hbeC1tbi8A=="], 1041 1047 ··· 1099 1105 1100 1106 "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], 1101 1107 1108 + "wisp-hosting-service/@atproto/api/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 1109 + 1102 1110 "wisp-hosting-service/@atproto/api/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 1111 + 1112 + "wisp-hosting-service/@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="], 1103 1113 1104 1114 "wisp-hosting-service/@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], 1105 1115 }
+2 -2
docs/src/content/docs/cli.md
··· 1 1 --- 2 - title: Wisp CLI 0.2.0 (alpha) 2 + title: Wisp CLI 0.4.0 (alpha) 3 3 description: Command-line tool for deploying static sites to the AT Protocol 4 4 --- 5 5 ··· 19 19 20 20 <div class="downloads"> 21 21 22 - <h2>Download v0.3.0</h2> 22 + <h2>Download v0.4.0</h2> 23 23 24 24 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download=""> 25 25
+4
package.json
··· 7 7 "apps/main-app", 8 8 "apps/hosting-service" 9 9 ], 10 + "dependencies": { 11 + "bun-plugin-tailwind": "^0.1.2", 12 + "tailwindcss": "4" 13 + }, 10 14 "scripts": { 11 15 "test": "bun test", 12 16 "dev": "bun run --watch apps/main-app/src/index.ts",
+5 -5
packages/@wisp/fs-utils/src/manifest.ts
··· 1 1 import type { Record, Directory } from "@wisp/lexicons/types/place/wisp/fs"; 2 - import { validateRecord } from "@wisp/lexicons/types/place/wisp/fs"; 2 + // import { validateRecord } from "@wisp/lexicons/types/place/wisp/fs"; 3 3 4 4 /** 5 5 * Create the manifest record for a site ··· 18 18 }; 19 19 20 20 // Validate the manifest before returning 21 - const validationResult = validateRecord(manifest); 22 - if (!validationResult.success) { 23 - throw new Error(`Invalid manifest: ${validationResult.error?.message || 'Validation failed'}`); 24 - } 21 + // const validationResult = validateRecord(manifest); 22 + // if (!validationResult.success) { 23 + // throw new Error(`Invalid manifest: ${validationResult.error?.message || 'Validation failed'}`); 24 + // } 25 25 26 26 return manifest; 27 27 }