# TokGlance > Production-ready Nuxt AI SaaS site with auth, billing, docs, dashboard, and AI workflows. Site: https://tokglance.com This file is generated from the current Nuxt Content docs/blog sources and configured site metadata. # Core Pages ## TokGlance URL: https://tokglance.com/ Summary: Production-ready Nuxt AI SaaS site with auth, billing, docs, dashboard, and AI workflows. Production-ready Nuxt AI SaaS site with auth, billing, docs, dashboard, and AI workflows. ## Pricing URL: https://tokglance.com/pricing Summary: Plans, billing options, and credit packaging for the product. Plans, billing options, and credit packaging for the product. ## Documentation URL: https://tokglance.com/docs Summary: Product documentation and implementation guides. Product documentation and implementation guides. ## Blog URL: https://tokglance.com/blog Summary: Product updates, implementation notes, and launch articles. Product updates, implementation notes, and launch articles. ## Changelog URL: https://tokglance.com/changelog Summary: Versioned product changes across the starter, dashboard, billing, and AI workspace. Versioned product changes across the starter, dashboard, billing, and AI workspace. # Documentation ## Introduction URL: https://tokglance.com/docs/introduction Locale: en Summary: What the Nuxt template already ships today, and where to customize it. The `web-nuxt` app is the Nuxt 4 frontend option in ZShip. It keeps landing pages, pricing, auth, blog, docs, and dashboard routes in one deployment. ### What ships today - Nuxt SSR plus Nitro server proxy routes under `server/api/*` - Built-in i18n, sitemap, robots, schema.org, ISR route rules, and image optimization - Shared landing UI, auth pages, dashboard routes, and localized navigation ### Where to customize it - `apps/web-nuxt/zship.app.json` controls `appKey`, domain, brand metadata, analytics IDs, `dashboard.url`, and `dashboard.features.*` - `apps/web-nuxt/app/config/site.ts` turns the manifest into runtime `siteConfig` - `apps/web-nuxt/content/docs/*` is the Nuxt Content source for the in-app docs - `apps/web-nuxt/server/api/*` is where server-side proxy routes live ### Skills-first customization If you want to modify `web-nuxt` through prompt-driven vibe coding, start with `Skills & vibe coding`. That page explains which repo skill to invoke for in-place template edits versus when to copy the app first and customize the copy. Set `dashboard.features.checkin`, `dashboard.features.tickets`, or `dashboard.features.referral` to `false` when the Nuxt dashboard should hide that entry and reject direct route access. ### When to use this frontend Choose `web-nuxt` when your team wants one Nuxt codebase for marketing, product, and server-side proxy logic, with clear configuration points for turning the template into a branded public site. ## Quick start URL: https://tokglance.com/docs/quick-start Locale: en Summary: Go from first visit to live demo, dashboard activation, and launch-ready trust surfaces. This guide is for teams evaluating the Nuxt template and for builders preparing the first public launch. ### 1. Verify the public funnel - Open the landing page while signed out and make sure the hero CTA sends visitors to `/guest-demo`. - Sign in and confirm the same hero CTA opens `/dashboard`. - Confirm the public header exposes pricing, docs, support, and blog. - Check that the footer shows a working contact email and a support entry. ### 2. Verify the product activation path - Visit `/guest-demo` and confirm a real guest session is provisioned. - Continue into `/dashboard/ai-playground` and make sure the same session still works. - Open `/dashboard` and confirm the homepage acts as an activation page instead of a plain account summary. ### 3. Verify auth and account conversion - Register a new account through `/auth/register`. - Make sure the post-login redirect lands in the dashboard and keeps the activation cards visible. - Confirm guest users can upgrade into a registered account without losing the main product path. ### 4. Verify credits and billing - Check `/pricing` for live plan data. - Open `/dashboard/credits` and confirm the balance matches the current session. - Review `/dashboard/subscription` and `/dashboard/orders` to verify billing history and plan status. ### 5. Launch checklist before going public - Update `apps/web-nuxt/zship.app.json` with the correct `domain`, `siteUrl`, `tagline`, and `contactEmail`. - Configure the `footer` block in `apps/web-nuxt/zship.app.json`; see `Footer configuration` for the field-by-field reference. - Review `dashboard.url` and `dashboard.features.checkin`, `dashboard.features.tickets`, `dashboard.features.referral` in `apps/web-nuxt/zship.app.json` so the dashboard only exposes the flows your product actually supports. - Review `seo.landingTitle` and `seo.landingDescription` in `apps/web-nuxt/zship.app.json` carefully, since they become the homepage's primary keyword signals; audit them before you go live and before you submit the sitemap. - Replace placeholder branding assets in `public/`. - Before launch, open Admin `/launch-check`; it verifies the selected project's Admin settings, backend fallbacks, service bindings, AI, Provider1, CDN/R2, pricing, and support surfaces. - Review the docs pages in this help center so support and billing expectations match your product. ### Recommended next reads - `Skills & vibe coding` - `Billing and credits` - `Footer configuration` - `Auth and guest mode` - `AI playground` - `Support and refund` ## Billing URL: https://tokglance.com/docs/billing-and-credits Locale: en Summary: How pricing, credits, subscriptions, and order history fit together in the Nuxt template. ZShip uses credits as the product-level spending unit and plans as the commercial packaging around those credits. ### What users can do - Compare plans on `/pricing` - Review current balance on `/dashboard/credits` - Inspect active subscription status on `/dashboard/subscription` - Review previous purchases on `/dashboard/orders` ### How the flow works 1. The visitor chooses a plan on the pricing page. 2. Checkout is created through the pay-service proxy. 3. Successful payment updates subscription state and the credit ledger. 4. Dashboard pages read the latest balance and order records from the same backend state. ### What to validate before launch - Pricing labels and descriptions match the plans configured in the pay service. - Credit amounts are easy to understand from a user perspective. - Refund expectations are documented and linked from support. - The support team knows which cases should go through tickets versus payment provider portals. ### Common launch questions #### When should I send users to pricing? Send users to pricing when they run out of credits, need a higher plan, or want to understand what each tier unlocks. #### Where should refund requests go? Use the support flow documented in `Support and refund`. The dashboard order history already exposes refund requests as a product-level action. ## Skills & vibe coding URL: https://tokglance.com/docs/skills-and-vibe-coding Locale: en Summary: Use repo skills to customize apps/web-nuxt with prompt-driven edits instead of starting from a blank spec. `web-nuxt` now has a dedicated skills entry for prompt-driven customization. The goal is simple: let a builder describe the product change in natural language, then let Codex map that request onto the right files and shared layers. ### Recommended skill stack - `$onboard` Use first when you need the repo map or want to confirm which layer owns a feature. - `$customize-web-nuxt` Use when you are editing `apps/web-nuxt` directly: landing hero, pricing, docs, auth, guest-demo, dashboard entry flow, or app-level proxy routes. - `$create-app` Use when you want a separate frontend copied from `apps/web-nuxt` instead of modifying the template in place. - `$customize-brand` Use after copying the app, or when the change is mostly manifest-driven branding and SEO. - `$add-page` Use when the new product surface needs its own route. - `$add-dashboard` Use when the user dashboard needs a new feature tab or activation area. ### In-place editing vs copied app Use `$customize-web-nuxt` when `apps/web-nuxt` itself is the working frontend. Use `$create-app` first if you want tenant isolation, a new package name, or a product frontend with its own release cadence. After that, use the other skills against the copied app. ### Main edit surfaces - `apps/web-nuxt/zship.app.json` Brand identity, SEO, footer, analytics, dashboard feature flags. - `apps/web-nuxt/app/components/LandingPage.vue` Hero, CTA flow, marketing sections, testimonials, closing CTA. - `apps/web-nuxt/app/pages/pricing.vue` Pricing layout, comparison table, sales CTA. - `apps/web-nuxt/content/docs/*` User-facing docs content in English and Simplified Chinese. - `apps/web-nuxt/server/api/*` Public-page server proxies. When a request clearly belongs to `packages/nuxt-common-layer` or `packages/nuxt-ai-layer`, Codex should explain that boundary before turning a local page tweak into a shared-platform change. ### Example prompts - `Use $customize-web-nuxt to turn the landing hero into a waitlist-first launch page for an AI video tool.` - `Use $customize-web-nuxt to simplify the dashboard home so the primary action is opening AI Playground.` - `Use $customize-web-nuxt to add a docs page about API keys and link it in the existing docs list.` - `Use $customize-web-nuxt to adjust pricing for annual plans only and update the CTA language across the landing page.` - `Use $create-app NAME=my-product to fork web-nuxt, then use $customize-brand APP=apps/my-product to replace the default branding.` ### Practical workflow 1. Start from the repo root. 2. Invoke the skill explicitly in your prompt. 3. Describe the product change, not just the file name. 4. Let Codex inspect the current implementation before patching. 5. Ask for verification on the affected route after the change lands. That approach keeps the work close to the real codebase and makes `web-nuxt` feel like a modifiable product surface instead of a frozen template. ## Auth and guest mode URL: https://tokglance.com/docs/auth-and-guest-mode Locale: en Summary: Understand login, guest access, account conversion, and where each path should lead users. The Nuxt template supports both registered accounts and guest sessions. The goal is to reduce friction before a user commits to sign-up. ### Registered account flow - Public entry: `/auth/login` and `/auth/register` - Supported modes: email, verification code, Google, GitHub - Post-login destination: `/dashboard` Registered users should land on the activation-oriented dashboard homepage and continue from there into AI, keys, billing, or support. ### Guest flow - Public entry: `/guest-demo` - Guest sessions are real authenticated sessions with their own credits and dashboard access - Guests should be encouraged to upgrade after they validate the workflow ### Upgrade guidance Guest mode is ideal for: - early product demos - marketing traffic that is not ready to sign up - sales conversations where you want a lower-friction proof point Registered mode is ideal for: - persistent usage - billing and subscriptions - API key management - long-term project ownership ### Product recommendation Do not treat guest mode as a dead-end sandbox. It should behave like a guided first session that naturally leads into account creation once the user sees value. ## AI workspace URL: https://tokglance.com/docs/ai-playground Locale: en Summary: The user-facing Chat, Image Agent, Studio, and Usage surfaces in web-nuxt. `web-nuxt` exposes a complete AI workspace instead of routing every workflow into one playground: - `/dashboard/ai-chat` is the persistent conversational product surface, including history and multi-turn continuation. - `/dashboard/ai-playground` is AI Studio for image, video, audio, and other structured generation workflows. - `/dashboard/image-agent` is a conversational image editing workspace with saved chats, reference images, generation history, a library, and version previews. - `/dashboard/usage` combines Chat and provider generation usage, including image, video, audio, requests, tokens, credits, daily activity, and model breakdown. ### Why it matters These surfaces share the same session lifecycle, so they already understand: - auth state - guest sessions - available credits - API key lifecycle - conversation and generation history - provider-specific inputs - user-scoped usage and billing data Site owners can keep the native Workers AI binding or configure any HTTPS OpenAI-compatible Base URL and API Key in the admin AI upstream settings. The credential remains server-side in `node10-ai-service`; users only see enabled models, never the upstream key. ### Recommended user path 1. Start from `/guest-demo` or `/dashboard` 2. Open `/dashboard/ai-chat` for conversational work or `/dashboard/ai-playground` for generation 3. Continue previous conversations or create the first result 4. Review `/dashboard/usage` before upgrading to a full account or a higher plan ### Image Agent setup Image Agent is currently included only in the Nuxt template. Its navigation is enabled by `imageAgent.enabled` in `app/app.config.ts`. The page and API live in `apps/web-nuxt`; other frontend templates are not connected. Reopening a conversation restores its most recent image model and generation settings. If that model is no longer available, select an available model before sending the next message. Background progress updates preserve the current model selection. The composer attachment panel supports file selection, drag and drop, clipboard images, HTTPS image links, and library selection. Each message accepts up to 16 images, with numbered previews, removal, and clear actions. Conversation images remain available for analysis even when the selected image model cannot edit images or accepts fewer source images. Image tools still enforce that model's capabilities and source count. File uploads reuse the platform CDN component with progress, cancellation, and retry, accepting PNG, JPEG, WebP, GIF, and AVIF files up to 10 MB each. Mock mode uses the same controls and validation while retaining files only in the browser, without contacting the CDN. You can discuss ideas before uploading an image or completing generation settings. The selected image model and settings apply when the Agent generates or edits an image; they do not prevent text discussion or visual analysis. Uploaded images are conversation context, and the Agent selects the permitted sources for each image operation. Assistant replies and activity messages support Markdown headings, emphasis, lists, tables and code blocks. Wide tables and code blocks scroll within the message on small screens. Model-supplied HTML stays plain text; replies do not load Markdown image URLs. Generated images and references are displayed from the saved task records. HTTP(S) links open separately. **Annotate image** opens an editor from reference thumbnails or image previews. It supports pen, arrows, rectangles, ellipses, text, colors, line width, movement, undo/redo, and modification notes. Each message accepts up to four annotated sources, with 64 marks and a 1,000-character note per source. The flattened PNG guide is uploaded through the shared CDN transport; the clean source, guide, normalized editable marks, and note are saved with the message. The Agent receives both images, while image editing tools receive only the clean source. Saved marks can be reopened for another edit. Live sources are imported into reference storage and read through an authenticated same-origin endpoint, so the editor does not require third-party browser CORS. Sources must be allowed by the import policy and remain accessible until their first successful copy. Inaccessible or oversized files show a retry state. Exported guides have a longest side of at most 2,048 pixels. The existing node10 Worker exports an Image Agent Cloudflare Workflow. Apply Node1 migrations through `0040_credit_debit_cancellation.sql`, enterprise billing through `0004_usage_reservation_fences.sql`, Provider1 through `0034_task_recovery_legacy_visibility.sql`, and node10 through `0016_image_agent_workflow_control.sql`. Release Node1 and enterprise billing, then Provider1, node10, and the Nuxt app. Use each service's `db:migrate:local` script for local development. Node10 needs `IMAGE_AGENT_WORKFLOW`, `PROVIDER1_SERVICE`, and a dedicated `IMAGE_AGENT_CREDENTIAL_KEY` secret containing 32 random bytes encoded as 64 hexadecimal characters. The frontend uses its existing `AI_SERVICE`, `PROVIDER1_SERVICE`, and CDN service connections. Configure an image provider with public model metadata, a prompt field, and an image reference field for editing. The model's validation schema supplies image settings and tool source limits. Provider Turnstile, access checks, moderation, credits, refunds, and task status handling still apply. In Cloudflare, the Admin AI proxy requires both `AUTH_SERVICE` for administrator verification and `AI_SERVICE` for Agent operations. The Nuxt Image Agent proxy requires `AI_SERVICE`; legacy image submissions also require `PROVIDER1_SERVICE`. Missing or failed bindings return an error without retrying through an HTTP URL, including when a write may already have committed. Local development outside Cloudflare continues to use the configured HTTP services. Run `pnpm --filter @zship/node10-ai-service test:admin-pages:local` to verify the compiled Admin API with actual local service bindings and `pnpm --filter @zship/web-nuxt test:server` for the Nuxt proxy regressions. These checks do not call models or replace hosted deployment verification. The shared Nuxt authentication and CDN upload proxies also require their configured bindings in Cloudflare. Password/refresh, Google and GitHub login requests are not resent through HTTP after a binding response is lost. Authentication outages preserve existing session cookies; a lost response may still mean the upstream already rotated the refresh credential. `pnpm --filter @zship/node10-ai-service test:nuxt-pages:local` builds and tests the Nuxt API with actual local platform services, including generation, editing, cold recovery, login, refresh, uploads and authenticated media. Inference uses controlled responses and the test stores are temporary. Add `--pages-browser` to serve the compiled page and its static assets after these checks; see the Node10 README for the fixture account, media routing and cleanup. Live OAuth providers, public media domains and hosted deployment still require separate verification. The template bundles literal Lucide and Simple Icons used by its active Nuxt layers, app manifest and UI icon defaults. Shared upload controls, model selection and navigation therefore render these icons from the client bundle in the production build. Custom runtime icon names need their own explicit bundle configuration. Open **AI Gateway > Image Agent** in Admin, or `/ai?tab=image-agent`, to choose the conversation model, enable new work, and set global limits. Choose an enabled model with valid token pricing that supports vision and tool calls; the model list does not certify its vision or tool quality. This conversation model is separate from the image model selected in the composer and uses the existing Workers AI or OpenAI-compatible gateway. Saving writes `IMAGE_AGENT_ENABLED`, `IMAGE_AGENT_MODEL`, and `IMAGE_AGENT_LIMITS` atomically through `/api/ai/image-agent/config`. Invalid stored policies disable new work and can be repaired from this tab. Without a configured conversation model, live submissions show the assistant as unavailable; local mock mode remains usable. The Admin tab lists runs by application, exact email, and status. **Needs attention** includes failed runs, waiting for credits, unpaid model calls, and unknown image operations. Detail shows frozen budgets, model usage, image operations, and event types without exposing prompts, credentials, image URLs, or raw provider payloads. `admin.provider.read` permits diagnostics; `admin.provider.write` permits configuration, stop, and resume. Initial verification must be completed by the user. Resume currently requires an active run with retained, unexpired credentials. Disabling new work preserves settlement for already accepted operations. **Response token limit** and **Reasoning effort** configure the conversation model, separately from image generation settings. The default is 1600 output tokens per call with provider-default reasoning. The output limit accepts 256–8192 tokens and includes reasoning tokens where the upstream counts them. Only select an explicit reasoning level when the upstream supports it. Saving also writes `IMAGE_AGENT_INFERENCE` in the same policy transaction. Each new run freezes these settings; changing them does not alter accepted runs. Higher limits can increase usage and latency. **Test model** in the Admin Image Agent tab checks image recognition, a structured tool call and adoption of its returned result through the same model adapter used by the Agent. It tests the selected model and current inference settings without saving the policy. The check makes at most two model calls, disables retries and uses the same 120-second upstream request timeout as live Agent calls. It can incur upstream model usage but creates no images and deducts no customer credits. Only administrators with provider write permission can start it. Configuration indicators mean **Configured**, not verified connectivity. Test results apply to the current screen and clear after changing the model or inference settings or refreshing; they are a basic connectivity/capability check, not a quality benchmark or a persistent release approval. A local Workers AI binding still needs authenticated remote inference to pass. **Test media** separately checks the reference-image storage path. It writes a unique tiny PNG to the configured R2 bucket, verifies the exact bytes through the public base URL, and removes the test object. It shows storage, public-read and cleanup results separately, with guidance for failures. This requires provider write permission and performs a few R2 operations without invoking a model, generating images, charging customer credits or adding user media records. A passed result verifies reference-media access from the Worker at that moment; image-provider delivery, model-side access and visual quality still require separate checks. Refreshing clears the result. Node6 honors the object's cache policy, so diagnostic files use `no-store`. A short R2 lifecycle rule for `image-agent/diagnostics/` can clean up files left by an interrupted check. If an Agent response reaches its output limit, the run stops before executing tool calls from that truncated response. Measured model usage is retained and settled, and any images created by earlier steps remain available. The workspace shows the response-limit reason and lets the user continue in a new message. Try this state locally with `?mock=1&case=workflow-output-limit`. The AI SDK agent can answer or clarify with text, inspect conversation images, and execute `generate_image` or `edit_image`. The Workflow waits for Provider results and supplies the resulting images back to the model, which can finish or perform a bounded revision. Image tools retain the selected provider, model and settings; source IDs resolve only to the conversation's images and current attachments. The activity timeline exposes persisted progress and intermediate images. Text-only replies do not create an image task or show an empty-image error. The Agent can focus its next visual inspection on one image or compare several selected images in order. Other image versions remain in the conversation and can be viewed again; they are excluded from the focused preview. Associated annotation guides accompany the selected sources. This helps isolate a detail when versions are confusing, but does not guarantee that the model's visual judgment is correct. Inspection uses model steps and tokens without creating an image operation. New tasks review newly returned images first. Results produced together are reviewed together; source images and earlier versions remain available for explicit comparison. A subsequent edit starts a fresh review of its outputs. Accepted tasks keep their original review policy during recovery. Conversation usage is charged separately at the configured model's token rates. New calls round positive usage up to whole credits, matching Node1's ledger: a calculated 0.14 credits costs 1 credit, while a free model remains free. Each response and exact billable amount are frozen before debit, using `image-agent:run::model:` as Node1's operation key. New paid runs require at least 1 credit in both balance and budget; D1 prevents a further model call with less than 1 credit remaining. Billing retries reuse the same amount and never repeat a completed inference; unpaid responses stay hidden. Settled calls create one platform usage record per run and step, including token counts and charged credits. Image Agent messages are excluded from ordinary AI Chat history. Defaults are six model steps, two image operations, 100 credits, and 30 minutes. Absolute server ceilings are eight steps, three operations, 1,000 credits, and 30 minutes. Admin can lower these caps for new runs; accepted runs keep their frozen limits. The composer clamps credit and operation inputs to the configured caps. Image-generation failures follow Provider's refund policy and do not refund completed conversation usage. New snapshots freeze billing version 1. Earlier accepted snapshots and saved legacy replies retain their original amounts and are never repriced during retries. Historical fractional debits cannot settle against the current integer-only Node1 ledger; they require explicit accounting reconciliation before a rollout containing such records. The local platform check (`pnpm --filter @zship/node10-ai-service test:platform:local`) runs the actual node10, Provider1 and Node1 Workers with disposable D1/R2 data and controlled external model responses. For persisted image tasks, Provider freezes the failure outcome and generation refund before contacting Node1. Failed refunds and lost refund responses remain pending and retry through status, authenticated callbacks, or the five-minute Provider recovery schedule. Refunds reuse `provider1:failure-refund:` and preserve moderation charges. The Agent shows **Returning image credits** and waits for settlement before its final reply; it does not repeat the failed image operation. A failed image operation leaves the run failed while preserving the assistant's explanation and any earlier successful images. Already completed dialogue usage is still billed. Historical failures without a frozen refund record require separate reconciliation. New Provider tasks and their frozen generation prices are persisted before generation billing. Unconfirmed payments cannot submit images. Payment uncertainty or a two-minute admission timeout cancels the original debit identity and refunds only its confirmed amount; Node1 blocks any delayed new debit with that key. Recovery retains the task ID and never submits a replacement image. Enterprise reservations use their original identity for cancellation. Moderation billing still precedes task creation, and acceptance uncertainty after the submission claim remains distinct from an unsubmitted billing failure. Content review persists its result and frozen price before charging, including reviews that stop before image task creation. If billing confirmation is lost, the Agent shows **Confirming content review charges** until Provider's scheduled recovery settles the original operation and its audit. Completed review fees are retained; no generation charge or refund is invented. Expired admission cannot generate an image even when the original caller returns late. Admin displays pending review charges as pending rather than zero. In local development, `?mock=1&case=workflow-review` previews this state and the final explanation while retaining the first image and draft. For enterprise Provider requests, image acceptance reserves usage; only final upstream success commits it. Provider saves the successful result before committing, then publishes task success after ledger confirmation. Lost responses recover the original operation through status, callbacks or the schedule, without generating again. Competing failure callbacks cannot cancel a saved success. Durable image delivery may still be pending after billing. Enterprise prices must use whole credits. Historical committed failures, orphan/fractional charges, permanent reservation denial and ambiguous upstream acceptance require separate reconciliation; existing committed invoices are not automatically cancelled. Each message freezes its parameters, ordered references, dialogue model rates, and run limits. Provider operations use `image-agent:run::image:`; transport retries and status reconciliation retain the original identity and API key. The browser reads durable progress through node10. **Stop task** revokes permission for further image work and retains results already accepted upstream; **Resume task** wakes the same run after reconnecting or adding credits. Scoped execution credentials are encrypted outside Workflow checkpoints, retained for at most one hour to settle accepted work, and cleared at terminal states. Rotated API keys cannot mutate an old run. Earlier messages retain their legacy execution path and identities. For terminal runs or expired execution credentials, **Reconcile existing results** uses the authenticated original API key to query existing Provider operations, settle saved model responses, and restore missing activity records. It never starts inference, submits images, changes accepted limits, or restarts the run. Pending image counts and frozen unpaid credits remain visible until resolved. Failed runs retain their terminal status; recovered images appear in the conversation and library. Uncertain submissions remain unresolved without authoritative Provider evidence, and lost model responses cannot be reconstructed by this action. Concurrent settlement and response-loss tests verify one ledger operation and one usage record per saved model call. Model quality determines how well edits preserve identity. Context uses the latest 24 messages and a bounded image catalog with visual references. Uploads and outputs use existing CDN/R2 delivery policy; authenticated history does not make public CDN URLs private. Chats with active Workflow messages cannot be archived. Archiving completed chats hides their history and library entries without deleting files. Recent chats, conversation history, and library reads are bounded at 100 records. Local authenticated start/events/resume/reconcile and Workerd restart tests use controlled model, Provider, and ledger substitutes. Admin browser tests cover desktop/mobile light/dark layouts, policy saves, permissions, filtering, and run controls with controlled Agent responses. Recovery browser tests cover pending results, partial settlement followed by an error, retry, and desktop/mobile light/dark layouts. Annotation tests cover editing, source/guide separation, save/reopen, touch input, cancellation, and transport retries. Real provider validation, complete source lineage, durable-media guarantees, and the release audit remain required before production release. New Workflow runs also require Provider migration `0027_required_image_delivery.sql`. Configure file transfer with an enabled R2 destination, a public base URL that serves that actual bucket, allowed upstream HTTPS origins, and rules selecting images from the mapped response. Provider currently binds the `zship-provider1` bucket; an unrelated CDN bucket cannot serve its objects. Missing storage configuration blocks authorization before model inference. When generation finishes but copying is pending, the timeline shows **Saving generated images**. Only fully saved results are delivered to the Agent. Storage retries retain the original task and fees, without generating again; terminal runs can continue delivery through reconciliation. Old accepted runs preserve their previous delivery policy. Complete historical source lineage, real configured inference, and release verification remain separate production requirements. #### Reference media Live image links are copied before entering the reference list. Node10's `IMAGE_AGENT_MEDIA` R2 binding uses the existing `zship-cdn` bucket, under `image-agent/references/`. Set `IMAGE_AGENT_MEDIA_PUBLIC_URL` to a public address that serves this bucket. For Node6's Worker file route, include `/file` in the base; a direct R2 custom domain uses its root. Both Workers must bind the same bucket. Set `IMAGE_AGENT_MEDIA_ALLOWED_ORIGINS` to a JSON array of trusted HTTPS origins, such as `["https://images.example.com"]`; the public media origin is also allowed. Up to 32 explicit origins are supported. The importer checks every redirect, never forwards user credentials, and limits downloads to 20 seconds, 10 MB and 32 million pixels. Supported formats are PNG, JPEG, WebP, GIF and AVIF. Model input support still depends on the selected upstream model. `POST /ai/image-agent/media/import` and `GET /ai/image-agent/media/:id/content` use normal Node1 API-key authentication and app/account ownership. D1 freezes each imported source identity and manifest. Conditional R2 writes let a retry recover already copied bytes after a lost checkpoint or an expired upstream URL. Original signed URLs are represented by hashes in the manifest storage and object metadata. Limits are 30 new import records per hour, 500 records per account/application, and two simultaneous transfers; failed records count toward the limits. A repeated source reuses its existing snapshot. Public result URLs still follow the platform's public CDN policy. The link panel retains the URL on failure, supports cancellation, and continues an import when closed. The editor reads stored bytes through Nuxt's authenticated same-origin proxy. New Workflow runs also copy every image in their bounded catalog and its associated annotation guides before model inference. This covers the latest 48 catalog entries plus current attachments, using the latest 24 messages. The activity timeline shows reference preparation. Each import has a recoverable checkpoint; a separate immutable D1 context freezes managed URLs, catalog IDs and attachment order. Storage failure or cancellation prevents new inference and image submission. The same import quotas and source allowlist apply to background imports, including legacy images that have never been copied. Historical guides become visible when the Agent inspects their clean source, labeled as past context. Guides never enter the editing tool's source catalog. Existing accepted runs retain their original replay behavior, and original message records are not rewritten. History, library and task reads project known references, guides and outputs to their saved URLs. Files that expired before any successful import cannot be recovered from a URL alone. Local checks cover actual Nuxt, node10, Node1, D1 and R2 using a public ZShip image. Controlled Workerd checks additionally verify reference/guide storage and frozen context across runtime restart, without paid inference. #### Image Versions Workflow results retain their run, operation and image IDs across later edits. Optional ordered `reference_ids` bind each selected version to its URL and owner when accepting a message; the field is immutable. New contexts assign stable media IDs to uploaded references, while generated versions retain their operation IDs. `GET /ai/image-agent/versions/:id` returns a version and its ordered sources using existing immutable operation records. The Nuxt preview exposes **Source images** and supports following parents, including compositions with multiple sources. The `composition` mock demonstrates this without uploading or generating images. Archiving hides conversations and library entries; owned image provenance remains readable for existing references. Older Workflow source IDs are resolved through their accepted catalog where possible. Legacy client-synchronized tasks lack authoritative operation records, and are not presented as verified Workflow provenance. Real configured model/provider validation and the release audit remain required. #### Local mock cases In `nuxt dev`, open `/dashboard/image-agent?mock=1`. The case menu includes single-image success, multi-turn edits (the default), multiple outputs, pending generation, failed generation, interrupted submission, an empty result, insufficient credits, and a new conversation. A case can also be linked directly, for example `?mock=1&case=failed`. Mock conversations, models, credits, uploads, and task responses stay in the page instance. Generation, billing, Turnstile, and CDN upload APIs are not called; ordinary app authentication checks may still run. Uploaded references use browser object URLs. Sending creates a pending task that completes on the next poll; **Resume task** resolves the seeded pending case, and **Try again** restores a failed request for resubmission. Rename, archive, library, preview, and download work with the sample records. Reloading or switching cases resets the sample data. The images are bundled demo fixtures, not responses from an AI model. Production builds ignore `mock=1` and retain normal authentication and generation. Case values: `success`, `edits`, `annotated`, `multiple`, `pending`, `failed`, `prepared`, `no-output`, `insufficient`, `empty`, `clarify`, `discussion`, `planning`, `agent-error`. `annotated` includes an original portrait, a background guide with editable rectangle/arrow marks, notes, and a sample warmer result. Selecting the original as a reference restores the saved guide for further annotation. The editing tool retains the clean original as its reference. Workflow cases: `workflow`, `workflow-delivery`, `workflow-credits`, `workflow-completed`, and `workflow-cancelled`. They show the shared activity timeline, intermediate results, saving generated images, stop controls, and waiting for credits. **Resume task** completes the running fixture; the credit-waiting fixture requires **Add demo credits** first. Cancelling preserves the first image. These cases simulate task states locally and do not start Cloudflare Workflows. `workflow-recovery` starts with an interrupted run, one retained image, one unresolved image, and one unpaid demo credit. **Reconcile existing results** restores the second image and activity record, settles the demo credit once, and leaves the original run failed. It does not start another generation. `workflow-refund` shows a failed revision waiting for its image refund. **Resume task** confirms the simulated refund, retains the first image, and finishes the run as failed with an explanatory reply. It returns 4 demo image credits and charges 1 demo credit for that final reply exactly once. The `clarify` case shows a follow-up question; the next message proceeds to a demo image task. The `discussion` case answers with text and does not generate another image. `planning` and `agent-error` can be resumed through the reply controls. These are deterministic fixtures, not local LLM inference. A new mock conversation response uses 1 demo credit, in addition to any demo image charge. Open `?mock=1&case=insufficient` to see the balance warning above the composer. It shows a balance of 0 and the selected model's estimated cost. **Add demo credits** adds 240 local credits, preserves the draft, and lets generation continue without a payment request. In live mode, the warning links to pricing in a new tab and offers a balance refresh; rejected submissions retain the draft. ### What product teams should avoid - Do not ask first-time users to paste a manual API key before they understand the product. - Do not collapse Chat and structured generation into competing interfaces; keep each entry point tied to a distinct job. - Do not separate credits, AI generation, and account state into unrelated pages without a guided default path. ## Support and refund URL: https://tokglance.com/docs/support-and-refund Locale: en Summary: Where users should go for help, how refunds are handled, and what to expose on the public site. Support should be visible before a user gets stuck. In ZShip, support is part of the public trust surface and part of the signed-in product flow. ### Public support surfaces - Header navigation should expose a support entry - Footer should expose a contact email - Docs should explain refunds and help expectations in plain language ### Signed-in support surfaces - `/dashboard/tickets` for product and account help - `/dashboard/orders` for purchase history and refund requests - `/dashboard/subscription` for plan status before contacting support ### Refund guidance Refund handling should be predictable: - explain when users should request refunds - point them to the correct ticket flow - keep plan and order information easy to inspect before they contact you ### What to customize before launch - `contactEmail` in `zship.app.json` - support copy in pricing, docs, and dashboard pages - internal process for ticket response times and refund review ## Analytics URL: https://tokglance.com/docs/analytics Locale: en Summary: Optional analytics support for GA4, Plausible, and Microsoft Clarity. `web-nuxt` now supports optional global analytics providers from `zship.app.json`. ### Supported providers - Google Analytics 4 via `analytics.googleAnalytics.measurementId` - Plausible via `analytics.plausible.domain` - Microsoft Clarity via `analytics.clarity.projectId` ### Consent flow Analytics scripts are no longer injected unconditionally. The app now waits for a consent decision before loading those providers. - Consent is persisted with a cookie plus local storage - A shared `useAnalytics()` wrapper exposes `track()` and page-view tracking - You can extend the same layer later for region-aware consent or first-party proxying ```json { "analytics": { "googleAnalytics": { "measurementId": "G-XXXXXXXXXX" }, "plausible": { "domain": "nuxt.zship.ai", "scriptSrc": "", "apiEndpoint": "" }, "clarity": { "projectId": "your-clarity-project-id" } } } ``` ### Next improvement path If you need stricter compliance, add a dedicated consent center or route analytics through first-party endpoints before turning on provider IDs in production. **Planned:** Cloudflare Web Analytics (RUM beacon) will be added as an optional provider via `analytics.cloudflareWebAnalytics.token`, alongside GA4 / Plausible / Clarity. See `docs/todo/cloudflare-web-analytics.md` in the repo. ## Footer configuration URL: https://tokglance.com/docs/footer-configuration Locale: en Summary: Configure footer brand copy, contact email, social links, navigation columns, legal text, and copyright from zship.app.json. The `web-nuxt` footer is manifest-driven. Edit `apps/web-nuxt/zship.app.json` and keep the footer content inside the top-level `footer` object. Do not hardcode footer copy, links, or legal text in `LandingFooter.vue`. The component should only render `siteConfig.footer`. ### Footer fields ```json { "footer": { "brandDisplay": "logo-and-site-name", "contactEmail": "support@example.com", "description": [ { "en": "Short product promise for the footer.", "zh-CN": "底部展示的简短产品说明。" } ], "socialLinks": [ { "labelKey": "footer_github", "to": "https://github.com/your-org/your-repo", "external": true, "icon": "i-simple-icons-github" } ], "sections": [ { "titleKey": "footer_section_product", "items": [ { "labelKey": "nav_pricing", "to": "/pricing" } ] } ], "disclaimer": [ { "en": "Optional legal or trademark disclaimer.", "zh-CN": "可选的法律或商标免责声明。" } ], "copyright": "© {year} {siteName}" } } ``` ### Field reference - `brandDisplay`: controls brand rendering. Use `logo-and-site-name`, `logo-only`, or `site-name-only`. - `contactEmail`: footer-specific email. Set it to an empty string to hide the email row. If the key is omitted, the app falls back to the top-level `contactEmail`. - `description`: one or more footer description lines. Use localized objects when the public site supports multiple locales. - `socialLinks`: icon buttons shown under the contact email. Each item needs `to`, `icon`, and either `labelKey` or localized `label`. Use an empty array to hide all social buttons. - `sections`: navigation columns. Each section uses `titleKey` or `label`, and each item uses `labelKey` or `label` plus `to`. - `disclaimer`: legal or trademark text shown in the bottom row. Use an empty array to hide it. - `copyright`: bottom-left copyright text. It supports `{year}`, `{siteName}`, and `{brandName}` tokens. Set it to an empty string to hide it. ### Labels and localization Use `labelKey` when a label already exists in `apps/web-nuxt/app/i18n/ui.json`: ```json { "labelKey": "footer_support", "to": "/docs/support-and-refund" } ``` Use localized `label` when the link is app-specific: ```json { "label": { "en": "Changelog", "zh-CN": "更新日志" }, "to": "/blog/changelog" } ``` Localized text objects can include `en`, `zh-CN`, `zh-TW`, or `default`. If the active locale is missing, the resolver falls back to the default locale or the first non-empty value. ### Link rules - Internal routes should start with `/`, for example `/pricing` or `/docs/quick-start`. - Hash links can use `/#section-id`. - External links should set `"external": true`. - Internal non-page assets such as `/llms.txt` can set `"localize": false` to keep the exact URL. - `mailto:` links are allowed, but footer email is usually clearer through `footer.contactEmail`. ### Launch checklist Before publishing the site: - Confirm `footer.description` no longer references the template if the product has been renamed. - Confirm `footer.contactEmail` reaches a real support mailbox. - Confirm every `footer.sections[].items[].to` route exists. - Confirm external links open the expected brand accounts. - Confirm `footer.disclaimer` matches your legal and trademark policy. - Run `pnpm --filter @zship/web-nuxt exec nuxt prepare`. ## Docs system URL: https://tokglance.com/docs/docs-system Locale: en Summary: The Nuxt Content docs setup inside web-nuxt and how to extend it. The in-app docs now run on Nuxt Content instead of a custom `marked` parser. ### What is included - Route-backed docs pages under `/docs` and `/docs/[slug]` - Markdown files stored under `content/docs/` - `content.config.ts` collections for English and Simplified Chinese docs - SEO metadata and prerender coverage for the docs routes - Shared sidebar navigation generated from the same content source ### Locale behavior The public site currently launches in English and Simplified Chinese. The docs source follows the same rule: English is always available, Simplified Chinese is added where it exists, and retired locale routes should redirect back to the canonical English or Simplified Chinese path. ### How to add a page 1. Add a markdown file under `content/docs/en/` 2. Add the matching Chinese file under `content/docs/zh/` if you want localized content 3. Use frontmatter for `title`, `label`, `description`, and `order` ```md --- title: Billing guide label: Billing description: Explain plans, invoices, and credits. order: 4 --- ## Overview Add your content here. ``` ### Where to extend next If docs volume grows, the next step is to build on the same Nuxt Content workflow with search, navigation metadata, or remote content sources instead of replacing the stack again. ## 模板概览 URL: https://tokglance.com/zh-CN/docs/introduction Locale: zh-CN Summary: 说明 web-nuxt 当前已经具备什么,以及主要改动入口在哪里。 `web-nuxt` 是 ZShip 里的 Nuxt 4 前台方案,把 landing、pricing、auth、blog、docs 和 dashboard 放在同一个部署里。 ### 当前已内置的能力 - Nuxt SSR + Nitro BFF,`server/api/*` 已代理常见后端请求 - 已接好 i18n、sitemap、robots、schema.org、ISR 路由规则和图片优化 - 已有 landing UI、认证页、仪表盘页,以及多语言导航 ### 主要改动入口 - `apps/web-nuxt/zship.app.json` 负责 `appKey`、域名、品牌信息、analytics ID、`dashboard.url` 与 `dashboard.features.*` - `apps/web-nuxt/app/config/site.ts` 把 manifest 转成运行时 `siteConfig` - `apps/web-nuxt/content/docs/*` 是站内 Docs 的 Nuxt Content 内容源 - `apps/web-nuxt/server/api/*` 用于扩展服务端代理路由 ### 用 skills 做 prompt 驱动改造 如果你希望通过自然语言 + vibe coding 的方式直接改 `web-nuxt`,先看 `Skills 与 vibe coding`。这页会说明什么时候该直接改模板,什么时候应该先复制出独立 app,再继续定制。 如果某个仪表盘功能不想对外暴露,可以把 `dashboard.features.checkin`、`dashboard.features.tickets` 或 `dashboard.features.referral` 设为 `false`,对应入口会隐藏,直接访问路由也会被拦住。 ### 什么时候适合选它 如果你的团队希望用一个 Nuxt 工程同时承载营销页、产品页和服务端代理,同时保留清晰的配置入口,把模板改造成自己的品牌前台,`web-nuxt` 很合适。 ## 快速开始 URL: https://tokglance.com/zh-CN/docs/quick-start Locale: zh-CN Summary: 从首次访问到真实演示、仪表盘激活路径与对外发布前检查清单。 这篇指南面向两类人:正在评估 Nuxt 模板的团队,以及准备把 `web-nuxt` 作为正式前台对外上线的开发者。 ### 1. 先验证公开转化链路 - 未登录时打开首页,确认主 CTA 指向 `/guest-demo` - 登录后再次打开首页,确认同一个主 CTA 指向 `/dashboard` - 检查头部导航是否能看到 pricing、docs、support、blog - 检查 footer 是否展示正确的联系邮箱与支持入口 ### 2. 再验证产品激活路径 - 打开 `/guest-demo`,确认系统会创建真实访客会话 - 从 demo 继续进入 `/dashboard/ai-playground`,确认会话仍然有效 - 打开 `/dashboard`,确认首页已经是激活页,而不是普通账户总览 ### 3. 验证登录与升级 - 通过 `/auth/register` 注册新账户 - 登录后确认会跳回仪表盘,并继续显示激活卡片 - 确认访客可以平滑升级为正式账户,而不会偏离主产品路径 ### 4. 验证计费与积分 - 在 `/pricing` 检查套餐是否是实时数据 - 在 `/dashboard/credits` 检查积分余额是否与当前会话一致 - 在 `/dashboard/subscription` 和 `/dashboard/orders` 检查订阅与订单状态 ### 5. 正式上线前必须替换的内容 - 在 `apps/web-nuxt/zship.app.json` 中补齐 `domain`、`siteUrl`、`tagline`、`contactEmail` - 在 `apps/web-nuxt/zship.app.json` 中配置 `footer` 区块;字段说明见 `Footer 配置` - 在 `apps/web-nuxt/zship.app.json` 中检查 `dashboard.url` 以及 `dashboard.features.checkin`、`dashboard.features.tickets`、`dashboard.features.referral`,确保仪表盘只暴露你的产品真正支持的功能入口 - 在 `apps/web-nuxt/zship.app.json` 中认真检查 `seo.landingTitle` 与 `seo.landingDescription`,它们会直接成为首页核心关键词信号;正式上线并提交 sitemap 前请逐字审核后再提交 - 替换 `public/` 下的品牌资源 - 上线前打开 Admin `/launch-check`,它会按项目检查管理端配置、后端 fallback、Service Binding、AI、Provider1、CDN/R2、价格和支持入口 - 逐页检查帮助中心文档,确保支持、退款与计费说明符合你的产品策略 ### 推荐继续阅读 - `Skills 与 vibe coding` - `计费与积分` - `Footer 配置` - `登录与访客模式` - `AI Playground` - `支持与退款` ## 计费与积分 URL: https://tokglance.com/zh-CN/docs/billing-and-credits Locale: zh-CN Summary: 说明定价、积分、订阅与订单历史在 Nuxt 模板中的关系。 ZShip 以前台的积分作为产品消耗单位,再用套餐和订阅来承载商业化。 ### 用户能做什么 - 在 `/pricing` 对比套餐 - 在 `/dashboard/credits` 查看当前积分余额 - 在 `/dashboard/subscription` 查看订阅状态 - 在 `/dashboard/orders` 查看购买记录 ### 一次完整链路如何工作 1. 用户在定价页选择套餐 2. 通过支付服务代理创建结账流程 3. 支付成功后更新订阅状态与积分账本 4. 仪表盘相关页面读取同一套后端数据并展示结果 ### 上线前应重点确认 - 套餐文案与支付后台配置保持一致 - 用户能清楚理解每个套餐对应多少积分 - 退款预期在支持文档中有明确说明 - 支持团队知道哪些问题走工单,哪些问题交给支付门户处理 ### 常见产品决策 #### 什么时候该把用户带去 pricing? 当用户积分不足、套餐不匹配,或者需要先理解商业模式时,都应该把他们带到 pricing。 #### 退款入口应该放在哪里? 建议统一走 `支持与退款` 文档说明的路径。订单页已经提供了产品侧的退款申请动作。 ## Skills 与 vibe coding URL: https://tokglance.com/zh-CN/docs/skills-and-vibe-coding Locale: zh-CN Summary: 通过 repo 里的 skills,用自然语言驱动方式修改和自定义 apps/web-nuxt。 `web-nuxt` 现在补了一套更适合 prompt 驱动改造的 skills 入口。目标很直接:让使用者先描述产品改动,再由 Codex 把请求映射到正确的页面、配置文件和共享层,而不是从一堆文件名开始猜。 ### 推荐的 skills 组合 - `$onboard` 先看仓库分层、确认某个功能到底归哪个 layer。 - `$customize-web-nuxt` 当你就是要直接修改 `apps/web-nuxt` 本体时使用。适合 landing hero、pricing、docs、auth、guest-demo、dashboard 激活路径、前台代理路由等改动。 - `$create-app` 当你不想继续直接改模板,而是希望先从 `apps/web-nuxt` 复制出一个独立前台时使用。 - `$customize-brand` 适合复制出独立 app 之后做品牌、SEO、footer、manifest 级配置。 - `$add-page` 适合新增独立页面和路由。 - `$add-dashboard` 适合给用户仪表盘增加新的功能页或新入口。 ### 什么时候直接改模板,什么时候先复制 如果当前工作对象就是 `apps/web-nuxt`,直接用 `$customize-web-nuxt`。 如果你需要租户隔离、独立包名,或者希望产品前台拥有自己的发布节奏,就先用 `$create-app` 复制,再对复制出来的 app 使用其它 skills。 ### 最常见的改动面 - `apps/web-nuxt/zship.app.json` 品牌信息、SEO、footer、analytics、dashboard feature 开关。 - `apps/web-nuxt/app/components/LandingPage.vue` 首页 hero、CTA、营销区块、社证内容、尾部 CTA。 - `apps/web-nuxt/app/pages/pricing.vue` 定价页结构、对比表、销售 CTA。 - `apps/web-nuxt/content/docs/*` 中英文站内文档内容。 - `apps/web-nuxt/server/api/*` 前台页面用到的服务端代理。 如果某个改动明显属于 `packages/nuxt-common-layer` 或 `packages/nuxt-ai-layer`,Codex 应该先说明边界,而不是把一个局部页面需求直接扩散成共享层大改。 ### 示例提示词 - `Use $customize-web-nuxt to turn the landing hero into a waitlist-first launch page for an AI video tool.` - `Use $customize-web-nuxt to simplify the dashboard home so the primary action is opening AI Playground.` - `Use $customize-web-nuxt to add a docs page about API keys and link it in the existing docs list.` - `Use $customize-web-nuxt to adjust pricing for annual plans only and update the CTA language across the landing page.` - `Use $create-app NAME=my-product to fork web-nuxt, then use $customize-brand APP=apps/my-product to replace the default branding.` ### 实际使用方式 1. 从仓库根目录开始。 2. 在提示词里显式写出 skill 名称。 3. 先描述产品改动目标,不要只丢一个文件名。 4. 让 Codex 先读现有实现,再补丁。 5. 改完后要求它在对应路由上做验证。 这样做的效果是:`web-nuxt` 会更像一个可以持续“边聊边改”的产品前台,而不是一个只能手工拆解的静态模板。 ## 登录与访客模式 URL: https://tokglance.com/zh-CN/docs/auth-and-guest-mode Locale: zh-CN Summary: 说明登录、访客访问、账户升级以及这些路径应该把用户带到哪里。 这个 Nuxt 模板同时支持正式账户与访客会话,目标是在用户真正注册前尽可能降低体验门槛。 ### 正式账户路径 - 入口:`/auth/login` 与 `/auth/register` - 支持邮箱、验证码、Google、GitHub - 登录后的默认目标页:`/dashboard` 正式用户进入后,应先看到激活导向的 dashboard 首页,再进入 AI、API Key、计费或支持相关页面。 ### 访客路径 - 入口:`/guest-demo` - 访客并不是伪造状态,而是真实会话,有自己的积分与可继续访问的 dashboard - 访客模式的目标是帮助用户先验证流程,再决定是否升级 ### 什么时候该鼓励用户升级 访客模式适合: - 对外演示 - 首次体验流量 - 销售或试用环节中的低门槛验证 正式账户适合: - 长期使用 - 订阅与计费 - API Key 管理 - 长期项目所有权 ### 产品建议 不要把访客模式做成死胡同式沙盒。更好的做法是把它做成一个“真实第一会话”,让用户在感受到价值后自然升级。 ## AI 工作区 URL: https://tokglance.com/zh-CN/docs/ai-playground Locale: zh-CN Summary: 说明 web-nuxt 面向用户的 Chat、Image Agent、Studio 与 Usage 产品面。 `web-nuxt` 现在提供完整的 AI 工作区,而不是把所有任务都导向一个 Playground: - `/dashboard/ai-chat` 是正式的持久化对话产品面,支持历史记录与多轮续聊 - `/dashboard/ai-playground` 是 AI 创作室,承载图像、视频、音频等结构化生成流程 - `/dashboard/image-agent` 是对话式图片编辑工作台,包含持久化对话、参考图、生成历史、素材库与版本预览 - `/dashboard/usage` 合并对话与 Provider 生成用量,覆盖图片、视频、音频、请求、Token、积分、每日活动和模型明细 ### 为什么要统一到这里 这些产品面共用同一套会话生命周期,因此都能理解: - 当前登录状态 - 访客会话 - 当前积分余额 - API Key 生命周期 - 对话与生成记录 - 模型差异化输入 - 按用户隔离的用量与计费数据 站长可以继续使用原生 Workers AI Binding,也可以在管理端 AI 上游配置中填写任意 HTTPS OpenAI 兼容 Base URL 与 API Key。凭证只保存在 `node10-ai-service` 服务端,用户只能看到已启用模型,不会接触上游密钥。 ### 推荐的用户路径 1. 从 `/guest-demo` 或 `/dashboard` 进入 2. 对话任务进入 `/dashboard/ai-chat`,生成任务进入 `/dashboard/ai-playground` 3. 继续历史对话或完成第一次生成 4. 在 `/dashboard/usage` 查看消耗,再按需升级正式账户或更高套餐 ### Image Agent 接入 目前仅 Nuxt 模板接入。`app/app.config.ts` 中的 `imageAgent.enabled` 控制导航入口;页面与 API 均位于 `apps/web-nuxt`,其他前端模板不受影响。 重新打开对话会恢复最近使用的图片模型与生成设置;如果原模型已经不可用,需要先选择可用模型再发送下一条消息。后台进度更新会保留当前模型选择。 输入区的图片附件面板支持文件选择、拖拽、剪贴板图片、HTTPS 图片链接和素材库多选。每条消息最多添加 16 张图片,显示缩略图与顺序编号,可预览、移除或清空。即使所选图片模型不支持编辑,或每次只接受较少的参考图,Agent 仍可查看这些对话附件;真正执行图片工具时,仍遵守该模型的能力与参考图数量限制。文件上传复用平台 CDN 上传组件,支持进度、取消和失败重试,接受单张最大 10 MB 的 PNG、JPEG、WebP、GIF、AVIF。Mock 使用相同界面和校验,文件仅保留在浏览器内,不请求 CDN。 没有上传图片或补齐出图设置时,也可以先讨论创意。所选图片模型与设置用于 Agent 生成和编辑图片,不会阻止纯文字讨论或看图分析。上传图片作为对话上下文保存,Agent 在每次图片操作中选择符合模型限制的来源图。 助手回复和执行记录支持 Markdown 标题、强调、列表、表格和代码块。小屏幕上的宽表格、代码块在消息内横向滚动。模型返回的 HTML 按普通文字展示,回复不会加载 Markdown 中的图片链接;生成图片与参考图通过已保存的任务记录展示。HTTP(S) 链接会单独打开。 参考图缩略图和图片预览中的“标注图片”可打开编辑器,支持画笔、箭头、矩形、椭圆、文字、颜色、粗细、移动、撤销重做和修改备注。每条消息最多包含四张已标注原图,每张最多 64 个标记和 1,000 字备注。合成的 PNG 指引图通过共用 CDN 上传,原图、指引图、可编辑的归一化标记和备注一起随消息保存。Agent 同时查看原图与指引图,图片编辑工具只使用不含标记的原图。保存后可重新打开并继续修改标记。真实模式先将原图导入参考图存储,再通过鉴权同源接口读取,因此编辑器不依赖第三方浏览器 CORS。来源须符合导入策略,并在首次转存成功前保持可访问;无法读取或超过大小上限时显示重试状态。导出指引图的最长边不超过 2,048 像素。 Agent 可将下一次视觉查看聚焦到单张图片,也可按所选顺序对比多张图片。其他版本仍保留在对话中,可再次查看,但不会混入聚焦预览。标注指引会随对应原图一起提供。这有助于在多个版本容易混淆时单独复核细节,但不保证模型判断必然正确。查看会消耗模型步骤与 token,不会执行图片生成操作。 新任务在出图后会先检查最新返回的图片,同一步产生的多张结果一起复核。原图和旧版本仍可主动选中进行对比;再次编辑后,重新检查本次输出。已接收任务在恢复时继续使用原有复核策略。 现有 node10 Worker 导出 Image Agent 的 Cloudflare Workflow。应用 Node1 截至 `0040_credit_debit_cancellation.sql`、企业账单服务截至 `0004_usage_reservation_fences.sql`、Provider1 截至 `0034_task_recovery_legacy_visibility.sql`、node10 截至 `0016_image_agent_workflow_control.sql` 的迁移,先发布 Node1 和企业账单服务,再按 Provider1、node10、Nuxt 的顺序发布。本地使用各服务的 `db:migrate:local` 脚本。node10 需要 `IMAGE_AGENT_WORKFLOW`、`PROVIDER1_SERVICE` 绑定,以及独立的 `IMAGE_AGENT_CREDENTIAL_KEY` Secret,值为 32 字节随机数编码成的 64 位十六进制字符串。前端沿用已有 `AI_SERVICE`、`PROVIDER1_SERVICE` 和 CDN 服务连接。图片 Provider 应配置公开模型信息、提示词字段和参考图字段,模型校验规则决定出图设置与工具可用的参考图数量。继续沿用 Provider 的 Turnstile、权限、内容审核、积分、退款和任务状态机制。 Cloudflare 环境中的 Admin AI 代理需要 `AUTH_SERVICE` 验证管理员,并通过 `AI_SERVICE` 调用 Agent。Nuxt Image Agent 代理需要 `AI_SERVICE`,旧式图片提交还需要 `PROVIDER1_SERVICE`。绑定缺失或失败时直接返回错误,不改走 HTTP 地址重试,包括写入可能已提交但响应丢失的情况。非 Cloudflare 本地开发继续使用配置的 HTTP 服务。可运行 `pnpm --filter @zship/node10-ai-service test:admin-pages:local` 验证编译后的 Admin API 与实际本地服务绑定,并运行 `pnpm --filter @zship/web-nuxt test:server` 检查 Nuxt 代理回归。这些检查不调用模型,也不替代远端部署验证。 共用 Nuxt 认证代理与 CDN 上传代理在 Cloudflare 环境中同样要求对应服务绑定。密码登录、刷新、Google 和 GitHub 登录不会在绑定响应丢失后改走 HTTP 重发。鉴权服务不可用时保留原会话 Cookie,但响应丢失仍可能意味着上游已轮换刷新凭据。`pnpm --filter @zship/node10-ai-service test:nuxt-pages:local` 构建 Nuxt API 并连接实际本地平台服务,检查生成、编辑、冷恢复、登录、刷新、上传与鉴权媒体读取。模型推理使用受控响应,测试存储为临时数据。追加 `--pages-browser` 可在检查通过后启动编译后的完整页面与静态资源;测试账户、媒体路由和清理方式见 Node10 README。实际 OAuth 供应商、公开媒体域名和云端部署仍需单独验证。 模板会将当前 Nuxt 层、应用清单和 UI 默认配置中使用的 Lucide、Simple Icons 字面量图标打入客户端包,生产构建中的上传控件、模型选择器和导航可直接显示这些图标。运行时动态提供的自定义图标名称仍需显式配置打包。 在 Admin 的 **AI Gateway > 图片 Agent** 中配置对话模型、新任务开关与全局额度,也可直接访问 `/zh-CN/ai?tab=image-agent`。请选择已启用、Token 定价有效且支持视觉输入和工具调用的模型;模型列表本身不证明其视觉或工具调用质量。这个对话模型与输入区选择的图片模型相互独立,沿用现有 Workers AI 或 OpenAI 兼容网关。保存通过 `/api/ai/image-agent/config` 一次写入 `IMAGE_AGENT_ENABLED`、`IMAGE_AGENT_MODEL` 和 `IMAGE_AGENT_LIMITS`。已存策略无效时会禁止新任务,可在此页面修复。未配置对话模型时,真实提交会显示图片助手暂不可用;本地 Mock 仍可体验。 管理页可按应用、完整邮箱和状态筛选任务。“需要处理”包含失败任务、等待积分、待付模型费用和图片状态待核实的记录。详情展示固定额度、模型用量、图片操作和事件类型,不返回提示词、凭据、图片 URL 或 Provider 原始响应。`admin.provider.read` 可查看诊断,`admin.provider.write` 可保存配置、停止和恢复任务。首次验证须由用户完成;当前恢复功能要求任务未结束,且保留的凭据未过期。关闭新任务不会阻止已接受操作继续结算。 “回复 Token 上限”和“推理强度”配置对话模型,与图片生成参数相互独立。默认每次调用最多输出 1600 Token,推理强度跟随上游默认值。输出上限可设为 256–8192;上游将推理 Token 计入输出用量时,二者共用此额度。仅在上游支持时指定推理强度。保存时在同一策略事务中写入 `IMAGE_AGENT_INFERENCE`,新任务会固定这些参数,之后修改配置不会改变已接受的任务。提高上限可能增加费用和等待时间。 Admin 图片 Agent 页的“测试模型”通过 Agent 使用的同一套模型适配器,检查图片识别、结构化工具调用和工具结果回传。可以使用当前推理参数测试所选模型而不保存策略;最多调用两次模型,关闭自动重试,上游请求超时与实际 Agent 调用一致,为 120 秒。测试可能产生上游模型用量,但不生成图片、不扣用户积分,仅 `admin.provider.write` 权限可执行。运行依赖中的“已配置”不代表连接已验证。结果只保留在当前页面,修改模型或推理参数、刷新后清除;这是基础连接与能力检查,不替代实际图片质量验证,也不是持久化的发布批准。本地 Workers AI 绑定仍需具备身份认证的远程推理能力才能通过。 “测试媒体”单独验证参考图存储链路:向配置的 R2 桶写入随机小 PNG,经公开地址核对原始字节后删除测试对象。页面分别显示写入、公开读取和清理结果,并提供失败处理提示。操作需要 Provider 写权限,会产生少量 R2 请求,但不调用模型、不生成图片、不扣用户积分,也不创建用户媒体记录。通过只代表当时 Worker 能访问参考图公开地址;图片 Provider 的交付、模型端访问和视觉质量仍需单独验证。刷新页面会清除结果。Node6 遵守对象缓存策略,诊断文件使用 `no-store`。可为 `image-agent/diagnostics/` 配置较短的 R2 生命周期规则,以清理测试中断遗留的文件。 Agent 回复达到输出上限时,会在执行该条截断回复中的工具调用之前停止任务,保留并结算真实模型用量。此前步骤已生成的图片仍可查看和继续编辑,界面会明确说明回复未完成,可以发送新消息继续。本地可用 `?mock=1&case=workflow-output-limit` 体验此状态。 AI SDK Agent 可以直接回答或追问、查看对话图片,并执行 `generate_image` 或 `edit_image`。Workflow 等待 Provider 完成后将实际图片结果交回模型,由模型决定结束或在额度内继续调整。图片工具保留用户所选 Provider、模型和设置,来源 ID 只能解析到当前对话图片和本次附件。执行过程展示持久化的步骤和中间图片。纯文字回复不会创建图片任务,也不会显示“没有返回图片”的错误。 对话按所配置模型的 Token 费率单独计费。新调用的正费用按整积分向上取整,与 Node1 账本一致:计算费用为 0.14 积分时实际扣 1 积分,免费模型仍不收费。每步回复和准确的应付金额先保存,再以 `image-agent:run::model:` 作为 Node1 操作键扣费;新付费任务的余额和预算均至少为 1 积分,D1 在剩余额度不足 1 积分时阻止下一次模型调用。结算重试复用原金额,不重复已完成的推理,未结算的回复不会展示。已结算模型调用按任务和步骤生成唯一的平台用量记录,包含 Token 数和已付积分;Image Agent 消息不会混入普通 AI Chat 历史。默认上限为六个模型步骤、两次图片操作、100 积分和 30 分钟;服务端绝对上限为八步、三次图片操作、1,000 积分和 30 分钟。Admin 可为新任务设置更低上限,已接受任务保留原额度;输入区的积分和操作次数会限制在已配置范围内。图片生成失败沿用 Provider 的退款规则,不退还已完成的对话费用。 新快照固定计费版本 1。此前已接受的快照和已保存的旧回复保留原金额,重试时不会重新定价。历史小数扣费无法在当前仅支持整数的 Node1 账本结算;如待发布环境存在这类记录,须先明确核对账务。`pnpm --filter @zship/node10-ai-service test:platform:local` 使用实际 node10、Provider1、Node1 Worker 和独立临时 D1/R2 数据执行平台检查,仅外部模型响应受控。 对于已经保存的图片任务,Provider 会先固定失败结果和生成退款金额,再调用 Node1。退款失败或退款响应丢失时保留待处理状态,通过状态查询、已认证回调或 Provider 的五分钟定时恢复任务重试。各路径复用 `provider1:failure-refund:`,保留已收取的审核费用。Agent 显示“正在退回图片积分”,确认结算后才继续最终回复,不重复失败的图片操作。图片操作失败会让整轮任务保留失败状态,同时保留解释文字和此前成功的图片;已完成的对话用量仍然计费。没有固定退款记录的历史失败需要单独核对账务。 新 Provider 任务与固定生成价格先入库,再处理生成扣费。未确认付款的任务不能提交图片;扣费结果不明或支付准入超过两分钟时,会取消原扣费键,仅退回已确认扣除的部分,Node1 阻止该键后续的新扣款。恢复保留原任务 ID,不提交替代图片。企业用量预约通过原身份取消。审核费用仍先于任务创建处理,取得提交资格后上游是否已接单不明,也与尚未提交的支付故障分别处理。 内容审核在扣费前保存审核结果与固定价格,涵盖图片任务创建前就中止的请求。扣费确认丢失时,Agent 显示“正在确认内容审核费用”,等待 Provider 定时恢复原计费操作并更新审核记录。已完成的审核仍收取审核费,不会虚构生成扣费或退款。生成准入过期后,即使旧请求迟到返回也不能生成图片。Admin 将待确认费用单独标记,不显示为零。本地可通过 `?mock=1&case=workflow-review` 查看待确认状态与最终说明,第一版图片和草稿都会保留。 企业 Provider 请求在图片接单时仅预约用量,上游最终成功后才提交费用。Provider 先保存成功结果,账本确认后才发布任务成功;响应丢失时通过状态查询、回调或定时任务恢复原操作,不重新生成。竞争的失败回调不能取消已保存的成功,图片转存可在计费后继续等待。企业生成与审核价格均须使用整数积分。历史已提交但生成失败的账单、孤立或小数扣费、永久预约拒绝、上游接单结果不明仍需单独核账,不自动取消已提交账单。 每条消息固定生成参数、有顺序的参考图、对话模型费率和运行额度。Provider 操作键为 `image-agent:run::image:`,网络重试和状态核对复用原身份及 API Key。浏览器通过 node10 查询持久化进度。“停止任务”撤销继续生成的授权,并保留上游已接受任务的结果;断线或补充积分后,“恢复任务”唤醒同一个后台任务。执行凭据按账号与应用加密保存在 Workflow 检查点之外,最长保留一小时用于核对已接受操作,结束后清除。切换 API Key 后不能修改旧任务。此前保存的消息仍沿用原执行路径和操作键。 任务已结束或执行凭据过期后,“核对已有结果”使用当前登录账号的原 API Key 查询原 Provider 操作、结算已保存模型回复,并补齐缺失的执行记录。它不启动推理、不提交图片、不修改原额度,也不重启任务。界面显示待核对图片数量和固定的待付积分,直至核对完成。失败任务保留原终态,恢复出的图片可在对话与素材库中使用。缺少 Provider 明确证据的提交继续标为待核实;丢失的模型响应不能由此操作重建。并发结算和响应丢失测试验证每个已保存模型调用只对应一笔账本操作和一条用量记录。 人物与产品的一致性取决于所选模型。上下文使用最近 24 轮消息和有数量上限的图片目录,包含视觉参考图。上传和生成结果沿用现有 CDN/R2 分发策略,对话鉴权不代表公开 CDN URL 自动成为私有文件。存在运行中 Workflow 消息的对话不能归档;归档已完成对话会隐藏历史和素材条目,不删除文件。最近对话、对话历史和素材库读取分别限制为 100 条记录。本地认证启动、事件、恢复、核对接口及 Workerd 重启测试使用受控模型、Provider 和账本替身。Admin 浏览器测试使用受控 Agent 响应,覆盖桌面和手机明暗主题、配置保存、权限、筛选与任务操作。核对界面测试覆盖等待结果、部分结算后报错、再次核对及桌面和手机明暗主题。标注验证覆盖编辑、原图与指引图分离、保存重开、触屏、取消与上传重试。正式发布前仍需完成真实 Provider 验证、完整图片来源关系、持久化媒体保障,以及发布审计。 新建 Workflow 还需要 Provider 迁移 `0027_required_image_delivery.sql`。请开启文件转存,配置能实际读取目标桶的公开地址、允许下载的上游 HTTPS 来源域名,以及从映射后响应中选取图片的规则。Provider 当前绑定 `zship-provider1` 桶,绑定其他桶的 CDN 入口不能读取这些结果。缺少存储配置时,会在对话模型运行前阻止授权。生成完成但图片仍在转存时,时间线显示“正在保存生成的图片”;只有全部保存成功后,结果才交给 Agent。文件重试保留原任务与费用,不重新生成;已结束任务可通过核对继续保存。此前已接受的任务保留原交付策略。完整历史来源关系、真实模型执行和发布验证仍是独立的上线要求。 #### 参考图存储 真实模式会先转存图片链接,再将其加入参考图。node10 的 `IMAGE_AGENT_MEDIA` R2 绑定使用现有 `zship-cdn` 桶,文件路径位于 `image-agent/references/` 下。`IMAGE_AGENT_MEDIA_PUBLIC_URL` 必须指向实际提供这个桶内容的公开地址。使用 Node6 Worker 的文件路由时,基础地址须包含 `/file`;直接绑定 R2 的自定义域名使用根路径。两个 Worker 必须绑定同一个桶。`IMAGE_AGENT_MEDIA_ALLOWED_ORIGINS` 是允许下载的 HTTPS 来源 JSON 数组,例如 `["https://images.example.com"]`,最多 32 个;公开存储地址的来源也默认允许。每次重定向都重新检查来源,不向第三方发送用户凭据。下载限时 20 秒,单图不超过 10 MB、3200 万像素,支持 PNG、JPEG、WebP、GIF 和 AVIF。实际模型可接收的图片格式仍由所选上游模型决定。 `POST /ai/image-agent/media/import` 和 `GET /ai/image-agent/media/:id/content` 沿用 Node1 API Key 鉴权,按应用与账户校验归属。D1 固定导入身份与文件清单,R2 使用条件写入;即使检查点保存失败或上游链接过期,重试也可恢复已保存的图片。存储记录和对象元数据仅保留原始签名链接的哈希。每个账户、应用每小时最多创建 30 条导入记录,总共 500 条,最多同时进行两次转存;失败记录也计入限额。重复链接沿用已保存的快照。公开图片地址仍遵循平台 CDN 的公开访问策略。 链接面板在失败时保留地址,支持取消,关闭面板后仍可继续导入。标注编辑器通过 Nuxt 的鉴权同源代理读取已保存字节。新建 Workflow 在调用模型前,也会转存有限图片目录中的全部图片及其标注指引:基于最近 24 轮消息,保留最近 48 个目录条目和当前附件。执行过程会显示参考图准备状态。每次导入有可恢复的检查点,独立且不可变的 D1 上下文固定存储地址、图片编号和附件顺序。存储失败或取消后不会开始模型调用或图片生成。后台转存沿用相同导入限额和来源白名单,包括此前尚未转存的旧图片。 Agent 查看历史原图时可同时查看标注指引,且明确标为过去的上下文;指引图不会进入编辑工具的原图目录。此前已接受的任务保持原来的重放行为,原始消息记录不会改写。历史、素材库和任务读取会将已保存的参考图、指引图和结果展示为存储地址。首次转存前就已过期的文件,无法仅凭链接恢复。本地验证覆盖真实 Nuxt、node10、Node1、D1、R2 和一张 ZShip 公开图片;受控 Workerd 测试还验证了参考图、指引图和固定上下文在服务重启后保持一致,未调用付费模型。 #### 图片版本 Workflow 结果在后续编辑中保留任务、操作和图片编号。可选的有序 `reference_ids` 在消息接受时校验每个版本对应的 URL 和账户归属,接受后不可修改。新上下文为上传参考图分配稳定的媒体编号,生成版本保留原操作编号。`GET /ai/image-agent/versions/:id` 根据现有不可变操作记录返回当前版本与有序来源。Nuxt 预览中的“来源图片”支持逐级查看父版本,也支持多张来源图合成;本地 `composition` 案例可直接体验,不上传或调用模型。 归档会隐藏对话和素材库条目,已有引用仍可读取本账户的图片来源。早期 Workflow 的编号会尽可能通过已接受的目录还原;由旧客户端自行同步的任务缺少权威操作记录,不会冒充经过核实的 Workflow 来源。真实模型与 Provider 联调以及发布审计仍需完成。 #### 本地 Mock 案例 在 `nuxt dev` 中打开 `/dashboard/image-agent?mock=1`。页面案例菜单包含单张成功、多轮改图(默认)、一次返回多张、生成中、失败重试、中断后恢复、成功但无图片、积分不足和空白对话。也可以直接通过 `?mock=1&case=failed` 分享具体案例。 Mock 对话、模型、积分、上传和任务响应仅存在于当前页面实例中,不调用生成、扣费、Turnstile 或 CDN 上传接口;应用原有的登录状态检查仍可能执行。上传参考图使用浏览器对象 URL。发送后先显示生成中,下次轮询返回图片;“恢复任务”可完成预置的生成中案例,“重试”可恢复失败请求并重新提交。重命名、归档、素材库、预览和下载均可操作样例记录。刷新或切换案例会重置数据。图片是随模板提供的演示素材,不是模型实际生成结果。生产构建忽略 `mock=1`,仍执行正常鉴权和生成流程。 案例参数:`success`、`edits`、`annotated`、`multiple`、`pending`、`failed`、`prepared`、`no-output`、`insufficient`、`empty`、`clarify`、`discussion`、`planning`、`agent-error`。 `annotated` 预置人像原图、带可编辑矩形和箭头的背景指引、修改备注及暖色结果样例。将原图用作参考图后可恢复已有标注继续修改,编辑工具仍以不含标记的原图作为参考。 后台任务案例:`workflow`、`workflow-delivery`、`workflow-credits`、`workflow-completed`、`workflow-cancelled`,展示同一套执行过程、中间图片、生成结果保存中、停止和积分等待界面。运行中案例点击“恢复任务”后完成;等待积分案例需要先“补充模拟积分”。停止后保留第一版图片。这些案例仅在本地模拟任务状态,不启动 Cloudflare Workflow。 `workflow-recovery` 预置一个已中断任务,保留第一张图,另有一张图片待核对和 1 模拟积分待结算。“核对已有结果”补回第二张图及执行记录,仅结算一次模拟积分,原任务仍保留失败终态,不发起新生成。 `workflow-refund` 展示图片调整失败后等待退款的过程。点击“恢复任务”会确认模拟退款,保留第一张图片,并以失败状态结束任务、展示解释回复。此过程仅退回一次 4 模拟图片积分,并收取一次最终回复的 1 模拟积分。 `clarify` 展示追问,补充下一条消息后进入演示图片任务;`discussion` 只返回文字,不生成新图片;`planning` 和 `agent-error` 可通过回复操作恢复。这些是固定案例数据,不是本地大模型推理。新一轮 Mock 对话消耗 1 模拟积分,图片任务另按演示模型计费。 通过 `?mock=1&case=insufficient` 可直接查看输入区上方的积分不足提示,显示当前余额 0 和所选模型的预计消耗。点击“补充模拟积分”会增加 240 本地积分,保留草稿并允许继续生成,不会发起支付请求。真实模式提供新标签页打开价格页面和刷新余额的入口;提交被拒绝时保留草稿。 ### 产品上应避免的做法 - 不要在用户还没理解产品前,就先要求他们粘贴手动 API Key - 不要把 Chat 与结构化生成塞进语义重复的界面;每个入口应对应明确任务 - 不要把积分、AI 生成与账户状态拆成彼此孤立的页面,却又没有默认引导路径 ## 支持与退款 URL: https://tokglance.com/zh-CN/docs/support-and-refund Locale: zh-CN Summary: 说明用户应该去哪里求助、退款如何处理,以及公开站点应暴露哪些信任入口。 支持入口应该在用户卡住之前就可见。在 ZShip 里,支持既属于公开站点的信任入口,也属于登录后的产品路径。 ### 公开支持入口 - 头部导航应该有 support 入口 - footer 应该展示联系邮箱 - docs 里要用清晰语言说明退款与帮助预期 ### 登录后的支持入口 - `/dashboard/tickets`:产品与账户问题 - `/dashboard/orders`:购买记录与退款申请 - `/dashboard/subscription`:联系支持前先自查套餐状态 ### 关于退款 退款流程应当可预测: - 明确告诉用户什么情况下应申请退款 - 把他们引导到正确的工单流程 - 在联系支持前,让他们能先看到清晰的订单与套餐信息 ### 上线前需要自定义的地方 - `zship.app.json` 中的 `contactEmail` - pricing、docs、dashboard 里的支持文案 - 团队内部对工单响应时间与退款审核标准的约定 ## 数据分析 URL: https://tokglance.com/zh-CN/docs/analytics Locale: zh-CN Summary: 说明 web-nuxt 目前如何接入 GA4、Plausible 和 Clarity。 `web-nuxt` 现在已经支持从 `zship.app.json` 配置可选的 analytics provider。 ### 当前支持的提供商 - Google Analytics 4,通过 `analytics.googleAnalytics.measurementId` - Plausible,通过 `analytics.plausible.domain` - Microsoft Clarity,通过 `analytics.clarity.projectId` ### 同意机制 分析脚本不再默认注入,只有用户明确同意之后才会加载。 - 同意状态会同时写入 cookie 和 local storage - 统一通过 `useAnalytics()` 暴露 `track()` 与页面浏览统计 - 后续如果需要按地区合规、第一方代理或更细粒度事件,可继续在这一层扩展 ```json { "analytics": { "googleAnalytics": { "measurementId": "G-XXXXXXXXXX" }, "plausible": { "domain": "nuxt.zship.ai", "scriptSrc": "", "apiEndpoint": "" }, "clarity": { "projectId": "your-clarity-project-id" } } } ``` ### 后续建议 如果生产环境需要更严格的合规控制,建议继续补上专门的 consent center,或走第一方代理后再启用 provider ID。 **规划中**:Cloudflare Web Analytics(RUM beacon)将作为可选 provider 接入 `analytics.cloudflareWebAnalytics.token`,与 GA4 / Plausible / Clarity 并存。详见仓库文档 `docs/todo/cloudflare-web-analytics.md`。 ## Footer 配置 URL: https://tokglance.com/zh-CN/docs/footer-configuration Locale: zh-CN Summary: 通过 zship.app.json 配置 Footer 的品牌文案、联系邮箱、社交链接、导航栏目、法律声明与版权信息。 `web-nuxt` 的 Footer 是配置驱动的。请编辑 `apps/web-nuxt/zship.app.json`,并把 Footer 相关内容放在顶层 `footer` 对象里。 不要把 Footer 文案、链接或法律说明硬编码进 `LandingFooter.vue`。组件只负责渲染 `siteConfig.footer`。 ### Footer 字段 ```json { "footer": { "brandDisplay": "logo-and-site-name", "contactEmail": "support@example.com", "description": [ { "en": "Short product promise for the footer.", "zh-CN": "底部展示的简短产品说明。" } ], "socialLinks": [ { "labelKey": "footer_github", "to": "https://github.com/your-org/your-repo", "external": true, "icon": "i-simple-icons-github" } ], "sections": [ { "titleKey": "footer_section_product", "items": [ { "labelKey": "nav_pricing", "to": "/pricing" } ] } ], "disclaimer": [ { "en": "Optional legal or trademark disclaimer.", "zh-CN": "可选的法律或商标免责声明。" } ], "copyright": "© {year} {siteName}" } } ``` ### 字段说明 - `brandDisplay`:控制品牌展示方式,可选 `logo-and-site-name`、`logo-only`、`site-name-only`。 - `contactEmail`:Footer 专用联系邮箱。设为空字符串可以隐藏邮箱行;如果省略该字段,会回退到顶层 `contactEmail`。 - `description`:Footer 左侧的描述文案,可以配置多行。多语言站点建议使用 localized object。 - `socialLinks`:邮箱下方的社交图标按钮。每一项需要 `to`、`icon`,以及 `labelKey` 或多语言 `label`。设为空数组可以隐藏所有社交按钮。 - `sections`:右侧导航列。每个栏目使用 `titleKey` 或 `label`,每个链接使用 `labelKey` 或 `label` 加 `to`。 - `disclaimer`:底部法律或商标声明。设为空数组可以隐藏。 - `copyright`:底部左侧版权文案,支持 `{year}`、`{siteName}`、`{brandName}`。设为空字符串可以隐藏。 ### 标签与多语言 已有翻译建议复用 `apps/web-nuxt/app/i18n/ui.json` 里的 `labelKey`: ```json { "labelKey": "footer_support", "to": "/docs/support-and-refund" } ``` 产品专属链接可以直接写多语言 `label`: ```json { "label": { "en": "Changelog", "zh-CN": "更新日志" }, "to": "/blog/changelog" } ``` 多语言对象可以包含 `en`、`zh-CN`、`zh-TW` 或 `default`。如果当前语言缺失,系统会回退到默认语言或第一个非空值。 ### 链接规则 - 站内路由以 `/` 开头,例如 `/pricing` 或 `/docs/quick-start`。 - 页面锚点可以写成 `/#section-id`。 - 外部链接需要设置 `"external": true`。 - `/llms.txt` 这类站内非页面资源可以设置 `"localize": false`,保留原始 URL。 - 可以使用 `mailto:` 链接,但 Footer 邮箱通常建议用 `footer.contactEmail` 管理。 ### 上线检查清单 正式发布前请确认: - `footer.description` 不再保留模板占位文案。 - `footer.contactEmail` 指向真实支持邮箱。 - 所有 `footer.sections[].items[].to` 都是存在的路由。 - 外部链接指向正确的品牌账号。 - `footer.disclaimer` 符合你的法律与商标使用策略。 - 执行 `pnpm --filter @zship/web-nuxt exec nuxt prepare`。 ## Docs 系统 URL: https://tokglance.com/zh-CN/docs/docs-system Locale: zh-CN Summary: 说明 web-nuxt 当前基于 Nuxt Content 的站内文档能力,以及如何继续扩展。 站内 Docs 现在已经改成基于 Nuxt Content 的内容流,不再依赖自定义 `marked` 解析管线。 ### 当前包含的部分 - `/docs` 和 `/docs/[slug]` 路由 - 存放在 `content/docs/` 下的 markdown 文件 - `content.config.ts` 里定义的英文与简体中文 docs collections - 已接入 SEO metadata 和 prerender - 由同一内容源生成的侧边栏导航 ### 语言策略 当前公开站点首发只提供英文与简体中文,docs 内容也遵循同样的范围:英文始终可用,已翻译的页面再补简体中文,其余已收口的 locale 路由会重定向回英文或简体中文 canonical。 ### 如何新增页面 1. 在 `content/docs/en/` 下新增 markdown 文件 2. 如果需要中文版本,再在 `content/docs/zh/` 下补对应文件 3. 通过 frontmatter 配置 `title`、`label`、`description`、`order` ```md --- title: 账单指南 label: Billing description: 说明套餐、发票和积分。 order: 4 --- ## 概览 在这里写正文。 ``` ### 下一步怎么升级 如果文档规模继续增长,下一步可以继续在 Nuxt Content 这一套上叠加搜索、导航 metadata 或远程内容源,而不是再换一套内容栈。 # Blog ## ZShip Product Changelog - July 2026 URL: https://tokglance.com/blog/changelog Locale: en Updated: 2026-07-16 14:45:51 Summary: Five July 2026 updates improve workflow reliability, email delivery, credit processing, Admin navigation, and mobile ElevenLabs input. This release brings together five product and platform updates prepared on July 16, 2026. The Admin interface update is already available; service-level improvements become active as their corresponding Workers and database migrations are rolled out. ### Safer provider workflow retries Provider generation requests now carry stable workflow context and idempotency data through creation, status polling, webhooks, credit deductions, and result transfer. Retrying the same request no longer creates duplicate work or duplicate credit deductions, while webhook tokens add a stronger verification boundary for asynchronous results. ### Usage-balanced Resend delivery Email delivery can now distribute traffic across eligible Resend keys while respecting daily quotas. The Admin email workspace includes key status, usage, routing preference, delivery logs, and localized management controls so operators can understand capacity before an email is sent. ### Faster configuration and credit processing Provider configuration updates now support batch operations and more deliberate cache invalidation. Subscription credit jobs use bounded queries and processing budgets, reducing repeated database work and making scheduled runs more predictable as account volume grows. ### A clearer Admin workspace The Admin shell now uses layered workspace tabs and integrated navigation. Parent menu groups open compact four-column matrices with icons above labels, allowing operators to scan more destinations at once. On mobile, the matrix opens below the selected group and stays within the viewport; light mode, dark mode, and localized labels are supported. ### Restored ElevenLabs dialogue input on mobile ElevenLabs Dialogue V3 once again exposes a required prompt in Quick Create. The prompt is mapped into the provider's dialogue payload with sensible stability and automatic language defaults, so mobile users can submit a valid dialogue request without constructing provider JSON manually. ### Rollout notes - Admin navigation is deployed independently through the Admin Pages project. - Provider idempotency and ElevenLabs input require the provider service migrations and Worker release. - Resend balancing requires the support service migration and Worker release. - Credit scheduling improvements require the authentication service Worker release. ## ZShip 2026 年 7 月产品更新日志 URL: https://tokglance.com/zh-CN/blog/changelog Locale: zh-CN Updated: 2026-07-16 14:45:51 Summary: 2026 年 7 月的五项更新覆盖工作流可靠性、邮件投递、积分处理、管理后台导航和移动端 ElevenLabs 输入。 本次更新汇总了 2026 年 7 月 16 日准备完成的五项产品与平台改进。管理后台界面已经上线;服务端能力会在对应 Worker 和数据库迁移发布后生效。 ### Provider 工作流重试更安全 生成任务从创建、状态查询、Webhook、积分扣减到结果转存,现在都会携带稳定的工作流上下文与幂等信息。重复提交同一请求不会重复创建任务或重复扣减积分,Webhook token 也为异步结果增加了更清晰的校验边界。 ### Resend 投递支持用量均衡 邮件投递现在可以在满足条件的 Resend 密钥之间分配流量,同时遵守每日配额。管理后台的邮件工作区补充了密钥状态、用量、路由偏好、投递日志和多语言管理控件,运营人员可以在发送前判断可用容量。 ### 配置更新和积分处理更高效 Provider 配置支持批量更新,并采用更明确的缓存失效策略。订阅积分定时任务使用有界查询和处理预算,减少重复数据库工作,让账号规模增长后的定时执行更加稳定可控。 ### 管理后台工作区更清晰 管理后台采用分层工作区标签页和融入式导航。点击父菜单会打开四列矩阵,图标在上、名称在下,可以一次扫读更多入口。移动端矩阵会在选中菜单下方展开并保持在视口内,同时支持浅色模式、深色模式和本地化文案。 ### 移动端恢复 ElevenLabs 对话输入 ElevenLabs Dialogue V3 的快捷创建重新提供必填提示词。提示词会被映射到 Provider 的 dialogue 请求结构,并带有合理的稳定性与自动语言默认值,移动端用户无需手写 Provider JSON 即可提交有效请求。 ### 发布说明 - 管理后台导航通过 Admin Pages 项目独立部署。 - Provider 幂等能力和 ElevenLabs 输入需要发布 Provider 服务迁移与 Worker。 - Resend 用量均衡需要发布 Support 服务迁移与 Worker。 - 积分定时任务优化需要发布 Auth 服务 Worker。