Workplace Translator is a mobile-first workplace communication assistant. It helps users decode workplace messages, understand possible subtext, choose a response intensity, and generate a reply that can be copied and sent.
Live site:
https://wt.liderrr.cc/
- Decodes workplace messages into implied intent and risk.
- Generates concrete next-step suggestions.
- Generates a copy-ready Chinese reply.
- Supports three target personas: boss, colleague, and client.
- Supports three response intensity levels.
- Supports either text input or image input.
- Compresses image input in the browser before sending it to the backend.
- Keeps AI credentials on the server side.
- Includes a Capacitor iOS project.
Browser UI
|
+-- src/pages/Home.jsx
| Collects persona, text/image input, and response intensity.
|
+-- src/pages/Result.jsx
Calls /api/translate and renders the structured AI result.
Serverless API
|
+-- api/translate.js
Vercel function entrypoint.
|
+-- server/glm-service.js
Validates input, builds GLM messages, calls GLM, parses JSON output.
GLM API
|
+-- Text model: glm-5.1
+-- Vision model: glm-4.6v
- React 19
- Vite 7
- React Router
- Tailwind CSS
- Framer Motion
- Lucide React
- Capacitor 8
- Vercel Serverless Functions
- GLM Chat Completions API
.
+-- api/
| +-- translate.js
+-- server/
| +-- glm-service.js
+-- src/
| +-- lib/
| | +-- glm.js
| | +-- utils.js
| +-- pages/
| | +-- Home.jsx
| | +-- Result.jsx
| +-- App.jsx
| +-- main.jsx
+-- ios/
+-- public/
+-- .env.example
+-- capacitor.config.ts
+-- vercel.json
+-- vite.config.js
+-- package.json
Create a local environment file:
cp .env.example .env.localRequired:
GLM_API_KEY=your-glm-api-key
Optional defaults:
GLM_API_BASE=https://open.bigmodel.cn/api/paas/v4
GLM_TEXT_MODEL=glm-5.1
GLM_VISION_MODEL=glm-4.6v
Do not commit .env, .env.local, or real API keys.
Install dependencies:
npm installStart the development server:
npm run devOpen:
http://localhost:5173/
Build for production:
npm run buildPreview the production build:
npm run previewThe frontend calls:
POST /api/translate
Request body:
{
"inputText": "Boss says this proposal needs more thought.",
"persona": "boss",
"fireLevel": 2,
"imageDataUrl": null
}Response body:
{
"subtext": "Analysis of the likely intent and risk.",
"actions": ["Action 1", "Action 2", "Action 3"],
"response": "A copy-ready reply."
}Rules enforced by the backend:
- Text input is trimmed and capped at 6000 characters.
- Image input must be a PNG, JPG, JPEG, or WEBP data URL.
- Image input is capped at 8 MB.
- Requests must include text or an image.
- API keys are read only from server environment variables.
Text-only requests use:
glm-5.1
Image requests use:
glm-4.6v
The browser sends image data as a data URL. The server validates it, strips the data:image/...;base64, prefix, and sends the raw base64 image to GLM.
This project is configured for Vercel.
Before deploying, configure these environment variables in the Vercel project:
GLM_API_KEY
GLM_API_BASE
GLM_TEXT_MODEL
GLM_VISION_MODEL
At minimum, GLM_API_KEY is required. Without it, the page can load but AI requests to /api/translate will return a service error.
Capacitor config:
appId: com.workplace.translator
appName: Workplace Translator
webDir: dist
Build and sync:
npm run build
npx cap sync iosOpen in Xcode:
npx cap open iosVerified locally:
npm run buildpasses.- Local Vite server responds at
http://localhost:5173/. - Production domain responds at
https://wt.liderrr.cc/. - Tracked files do not contain the GLM API key.
- Text GLM request works with
glm-5.1. - Image GLM request works with
glm-4.6v.
Known dependency audit state:
npm auditcurrently reports 8 issues: 1 moderate and 7 high.- They are dependency-level advisories and should be reviewed before running
npm audit fix, because automatic fixes may change lockfile and dependency behavior.
- Never expose GLM credentials in frontend code.
- Keep API credentials in local
.env.localor Vercel environment variables. - Do not commit local browser test artifacts such as
.playwright-mcp/. - The old Dify workflow has been replaced by the GLM API.
src/lib/dify.jsremains only as a compatibility guard and throws if called.