106 lines
12 KiB
Markdown
106 lines
12 KiB
Markdown
# Web Tools Agent Guide
|
|
|
|
This file is mandatory for AI and coding agents working in this repository. Read `README.zh-CN.md` in full before changing code. It is the authoritative product, behavior, deployment, extension, and release document; `README.md` is a complete English overview.
|
|
|
|
## First actions in a new session
|
|
|
|
1. Run `git status --short --branch` and preserve all existing tracked and untracked work. Never revert, overwrite, or clean user changes without explicit permission.
|
|
2. Read the closest existing tool component, its `src/lib/` implementation, Worker if present, and related tests before editing behavior.
|
|
3. Inspect `shared/tool-catalog.json`, `shared/default-navigation.json`, and `src/tools/registry.ts` before adding or removing a tool.
|
|
4. Do not commit, create tags, or push unless the user explicitly requests that action in the current conversation. Never place access tokens or credentials in source, Git configuration, documentation, commands committed to the repository, or release artifacts.
|
|
5. Make source changes only. Do not edit generated `dist/`; rebuild it with `npm run build`.
|
|
|
|
## Product identity and non-goals
|
|
|
|
- Web Tools is a self-hosted Vue 3 + TypeScript browser-local tools application with a zero-dependency Node.js static/configuration server.
|
|
- The default production port is `9000`. Port `8081` is only the local Vite development proxy target.
|
|
- The application is anonymous. Do not add login, accounts, favorites, sponsorship, analytics, telemetry, advertising, CDN assets, or a database.
|
|
- Tool inputs, keys, files, images, and results must remain inside the current browser tab. Do not send them to the Node server, a third-party API, or any remote service.
|
|
- `/setting` is a fixed, unlisted route for navigation management. It has no authentication and is not a security boundary. Anyone who can access the application can open it and change the globally shared navigation order.
|
|
- The server persists only navigation configuration. Preserve `data/navigation.json` and the configured external data directory; writes must remain temporary-file plus atomic-replace operations.
|
|
- Multiple users and tabs may use every tool concurrently. Their calculation state must remain independent; only navigation order is globally shared.
|
|
|
|
## Architecture rules
|
|
|
|
- `package.json` is the sole authoritative application version.
|
|
- `shared/tool-catalog.json` is the authoritative category/tool catalog. `shared/default-navigation.json` defines first-run ordering.
|
|
- Each tool is an independent lazy-loaded Vue component under `src/tools/`; register it in `src/tools/registry.ts`.
|
|
- Routes and sidebar entries are generated from the registry and catalog. Do not manually add an ordinary tool route to `src/router.ts`.
|
|
- Put parsing, encoding, cryptography, validation, and file-generation logic in testable modules under `src/lib/`. Vue components own presentation and state, not algorithm implementations.
|
|
- Put expensive file parsing and calculation in `src/workers/`. Workers still run entirely in the browser.
|
|
- Prefer browser standard APIs or existing, reviewed dependencies. Do not hand-roll established cryptographic primitives or file parsers.
|
|
- Add dependencies only when necessary. Keep the Node server runtime dependency-free unless a requirement cannot reasonably be met with the standard library.
|
|
- Define and enforce resource limits for file sizes, record counts, blocks, decoded image dimensions, random output, and rendered syntax tokens. If a limit changes, update implementation constants, tests, and the limits table in `README.zh-CN.md` together.
|
|
|
|
## Stable tool behavior
|
|
|
|
- ASCII/Hex uses UTF-8. Hex input accepts continuous text or chunks separated by whitespace, English commas, or Chinese commas, with an optional `0x` prefix on each chunk. Invalid UTF-8 must fail rather than silently replace bytes.
|
|
- Base64 supports standard and URL-safe input. Decoded output supports strict UTF-8, continuous Hex, and `0xNN, ...` byte arrays. Reject invalid characters, padding placement, lengths, and non-canonical trailing bits.
|
|
- AES-128-CMAC follows RFC 4493. The key is exactly 16 bytes of Hex and accepts continuous input or whitespace/comma/Chinese-comma-separated chunks with optional `0x` prefixes. Hex messages use the same parser.
|
|
- CRC supports BIN and multi-block Intel HEX, CRC-8/16/32/64 presets, and custom `Width`, `Poly`, `Init`, `XorOut`, `RefIn`, and `RefOut`. Combined data is ordered by address without filling gaps, and per-block results remain available.
|
|
- Firmware Hash accepts Intel HEX and computes SHA-256 and SHA-512. Effective-data mode concatenates sorted blocks without gap filling. Block-header mode prepends exactly two binary uint32 values, `startAddress` and data-only `dataLength`, to every block. Both fields are four bytes; Big Endian is the default; total input is `Header1 || Data1 || Header2 || Data2 ...`. Never hash a textual Hex representation of the header.
|
|
- RSA allows 2048, 3072, and 4096-bit keys with public exponent 65537. Prefer Web Crypto; the node-forge fallback must be seeded from `crypto.getRandomValues`. Export public SPKI PEM, private PKCS#8 PEM, and separately copyable N/E continuous Hex or byte arrays.
|
|
- Secure random output comes only from `crypto.getRandomValues`, is limited to 1-65,536 bytes, and supports continuous Hex, spaced Hex, and byte arrays. Changing display format must not regenerate bytes.
|
|
- JSON/XML formatting, minification, validation, and syntax highlighting stay local. When highlighting limits are exceeded, render the complete result as plain text rather than truncating it.
|
|
- PNG/ICO processing stays local and must enforce both compressed-file and decoded-pixel limits before costly rendering or allocation.
|
|
|
|
## Intel HEX and asynchronous safety
|
|
|
|
- Treat every address, length, end-address, offset, and allocation calculation as checked uint32 arithmetic. JavaScript bitwise operators are signed 32-bit and must not be used as unchecked address arithmetic.
|
|
- Validate record syntax, byte counts, checksums, control-record lengths/addresses, EOF placement, extended addresses, and the `0xFFFFFFFF` boundary.
|
|
- Sort records by absolute address, merge contiguous records, deduplicate identical overlaps, and reject conflicting overlaps. Enforce record, block, and effective-byte limits before allocating combined buffers.
|
|
- CRC and Firmware Hash may share the reviewed Intel HEX parser but must keep separate calculation logic, Worker protocols, and Vue state.
|
|
- File replacement, clear, mode change, option change, repeated generation, and component unmount can invalidate asynchronous work. Terminate obsolete Workers where possible and use monotonically increasing request/version IDs. A stale Worker, file read, image decode, or key-generation result must never replace current state.
|
|
- Clear the native file input value after handling a selection so choosing the same file again still emits a change event.
|
|
- Worker messages must be correlated to both the active Worker instance and active request ID. Error and completion handlers must ignore stale instances.
|
|
|
|
## UI contract
|
|
|
|
- Preserve the application shell: navigation on the left and tool content on the right on desktop; responsive navigation and a vertical content flow on mobile portrait.
|
|
- All tools use the shared visual language. Prefer `ToolPage`, `TextEditor`, `ModeTabs`, existing form/action classes, Lucide icons, and `src/styles.css`; do not create a tool-specific theme.
|
|
- Keep desktop controls compact. Use stable grid/flex constraints and allow controls to become full-width where appropriate on narrow screens.
|
|
- Prevent horizontal page overflow, clipped controls, nested scrolling accidents, text overlap, layout shifts, and unbounded result columns. Long Hex, hashes, filenames, and table cells require explicit wrapping or contained scrolling.
|
|
- Version information remains at the bottom of the sidebar and is read from `package.json`. Every page footer displays exactly `Copyright © mid All Rights Reserved.`
|
|
- Do not add a visible link to `/setting`, explanatory marketing copy, login UI, favorites, or sponsorship UI.
|
|
- For UI work, verify a wide desktop, an intermediate width around 801-1040 px, and mobile portrait around 390 x 844 in a real browser. Check direct routes, refresh, navigation, search, `/setting`, both themes, console errors, and network requests.
|
|
|
|
## Adding a tool
|
|
|
|
1. Choose a permanent, unique kebab-case ID. Published IDs must not change because routes and saved navigation depend on them.
|
|
2. Add pure logic and normal, invalid, boundary, resource-limit, and known-vector tests.
|
|
3. Add one Vue component under `src/tools/` using shared components and responsive styles.
|
|
4. Add matching metadata to `shared/tool-catalog.json` and its default position to `shared/default-navigation.json`. Only change navigation `version: 1` for a schema migration, not for a new tool.
|
|
5. Register the Lucide icon and lazy component in `src/tools/registry.ts`. Do not add a manual route.
|
|
6. Verify that an old saved `navigation.json` retains its order and receives the missing tool after the Node process restarts and navigation is next loaded.
|
|
|
|
IDs must remain synchronized across the catalog, default navigation, icon map, and component registry. Existing catalog tests enforce this contract.
|
|
|
|
## Deployment and release
|
|
|
|
- Supported deployments are Docker and Node.js 22.12.0+ with `web-tools.ps1` on Windows Server. A Windows single EXE is an optional future deliverable and is not currently built or supported.
|
|
- Keep production port changes synchronized across `server/index.mjs`, `web-tools.ps1`, `Dockerfile`, `docker-compose.yml`, `.env.example`, deployment tests, and both READMEs where applicable.
|
|
- The Windows update flow requires a clean `main` checkout and uses `git pull --ff-only`. Preserve external `C:\ProgramData\WebTools\data` state.
|
|
- New catalog data is loaded by the Node process at startup. Rebuilding `dist` alone is insufficient after catalog changes; restart the server and refresh already-open browser pages.
|
|
- If a single EXE is later authorized, use Node.js SEA with embedded read-only web/catalog assets and an external writable data directory. Add per-architecture builds, asset-read abstraction, Windows smoke tests, replacement/update instructions, and optional Authenticode signing. Derive EXE version metadata from `package.json`; do not create another manually maintained version source. Do not commit generated executables.
|
|
|
|
For a release, synchronize these five tracked files:
|
|
|
|
1. `package.json`
|
|
2. `package-lock.json`
|
|
3. `docker-compose.yml`
|
|
4. `README.zh-CN.md`
|
|
5. `CHANGELOG.md`
|
|
|
|
Use `npm version patch --no-git-tag-version` or the appropriate minor/major form so the project version in `package.json` and the two project metadata entries in `package-lock.json` remain synchronized. Other lockfile `version` fields belong to dependencies. `README.md` intentionally does not hardcode the current version.
|
|
|
|
Rebuild `dist`, the requested delivery ZIP, optional Docker image tar, and SHA-256 checksums. Generated assets are release outputs and remain ignored by Git. Never include `node_modules`, `.env`, runtime data, credentials, or local logs.
|
|
|
|
## Required validation and handoff
|
|
|
|
- After every code or documentation change, run `npm run check` and `git diff --check`.
|
|
- Before a release, also run `npm audit --audit-level=low`.
|
|
- For server/deployment changes, validate PowerShell syntax and Docker Compose configuration when the required executables are available. State clearly when a platform-specific check could not be run.
|
|
- For UI changes, complete the browser matrix in the UI contract. Automated tests and a successful build do not replace visual verification.
|
|
- Report changed behavior, important format/compatibility decisions, tests actually run, and any remaining risk. Report artifact paths and SHA-256 only when the task requested artifacts.
|
|
- Do not claim a check passed unless it was actually executed in the current worktree.
|