Imported from riya-amemiya/UMT (
AGENTS.md). Install upstream withnpx skills add riya-amemiya/UMT. Copyright stays with the author.
AGENTS.md
This file contains instructions and guidelines for AI agents working on the UMT (Universal Math Tool) repository.
Overview
UMT is a collection of useful utility functions. The primary implementation and source of truth is the TypeScript package located in package/main. Other language implementations (package/umt_python, package/umt_rust) are ports that must maintain strict parity with the TypeScript version's behavior and API where applicable.
General Rules
- Source of Truth:
package/main(TypeScript) defines the expected behavior. When in doubt, consult its implementation and tests. - No TODOs: Do not leave TODO comments in the code.
- No Git Conflict Markers: Ensure all conflict markers (
<<<<<<<,=======,>>>>>>>) are resolved and removed. Their presence will fail CI immediately. - Verification: Always verify changes by running the appropriate test and lint commands for the specific package.
- No benchmark comments: Do not put timing numbers, "~Nx faster", ns/call, op counts, or runtime versions in source comments. Put measurements in the PR description only. Comments should explain non-obvious behavior, not recap a microbenchmark.
- Nix is formatter-only: Use
nix fmtfor Nix (and root YAML) formatting. Do not wrap build, test, or lint innix develop.
Package: main (TypeScript)
Located in package/main.
- Runtime: Uses Bun.
- Setup:
bun install - Testing:
bun run test(runs Jest) - Linting:
bun run lint(runs ESLint, Biome, and TSC) - Formatting:
bun run format(runs Biome) - Nix:
nix fmtonly. Scripts callmakedirectly. - TypeScript pin: Keep
typescriptat 6.0.3 inpackage/main,package/umt_i18n, andpackage/umt_wasm. TypeScript 7.x currently breakstypescript-eslint(lint:ci) andts-nodeloadingjest.config.ts(Node 20npx jest). Seepackage/main/COMPATIBILITY.md.
Note: The types directory primarily contains type definitions. Porting logic from types is only necessary if it corresponds to runtime logic.
Package: umt_python (Python)
Located in package/umt_python.
Tooling
- Manager: Uses uv.
- Commands (run from
package/umt_python):make test: Runsuv run pytest.make lint: Runsuv run ruff checkand format checks.make format: Runsuv run ruff format.make typecheck: Runsuv run pyright.
Coding Standards & Parity
- Typing:
- Use
int | float(Python 3.10+ pipe syntax) for numeric arguments. - Avoid
typing.Any; useobjectif necessary (RuffANN401). - Explicitly check
isinstance(n, bool)and returnFalsein numeric validation functions, as Python treatsboolasint.
- Use
- Math:
- Use
decimal.Decimal(initialized from strings) for exact arithmetic to match JavaScript's behavior and avoid floating-point errors. - Use
math.isqrtfor integer square roots. - When using
math.combormath.perm, explicitly cast results tofloatand ensureNaNhandling matches the TS implementation.
- Use
- Linting (Ruff):
SIM108: Use ternary operators for simple conditionals.UP035: Import fromcollections.abcinstead oftyping(e.g.,Callable,Iterable).PERF203: Avoidtry-exceptblocks inside loops.
- Testing & Benchmarks:
- Unit tests must import from
src(e.g.,from src.validate import ...). - Benchmarks reside in
tests/benchmark/and usetimeit. Note that__file__is not defined intimeitstrings; resolve paths externally.
- Unit tests must import from
Package: umt_rust (Rust)
Located in package/umt_rust.
Tooling
- Manager: Cargo.
- Commands:
cargo test: Run unit and integration tests.cargo fmt: Format code (required for CI).cargo clippy: Run lints.
Coding Standards & Parity
- Core Logic:
- Stable Rust Only: Do not use unstable features like
let_chains. - Value Enum: Use
umt_rust::object::Valuewith#[serde(untagged)]for JSON interoperability. Use theobj!macro for construction. - Regex: Cache compiled
regex::Regexvalues instd::sync::LazyLockstatics (umt_strip_ansi,umt_strip_tags,umt_words,hexa_to_rgba, UA extractors). Do not compile a fixed pattern on every call. Patterns built from caller input (calculator,format_string,umt_regex_match) stay inline. - Math:
- Implement
apply_currency_exchangefor currency conversion. - Operator precedence: Exp > Mul/Div > Add/Sub.
- Rounding: Explicitly round floating-point results (e.g.,
(val * 1e10).round() / 1e10) before string conversion to match TS precision.
- Implement
- Stable Rust Only: Do not use unstable features like
- Clippy & Lints:
for_kv_map: Iterate over.keys()or.values()if only one is needed.manual_strip: Usestr::strip_prefixinstead ofstarts_withand slicing.module-inception: File names should matchpackage/main(e.g.,calculator.rs) even if it triggers this lint (allow if necessary, but prefer structural fixes).
- Testing:
- Tests must be in the
tests/directory (integration style), not insrc/. - Benchmarks are integration tests in
tests/benchmark/usingstd::time::Instant. - Integration tests in subdirectories must be registered in a root test file (e.g.,
tests/integration/mod.rs).
- Tests must be in the
Package: umt_wasm (WebAssembly)
Located in package/umt_wasm. Auto-generated wasm-bindgen wrappers over umt_rust.
- Generate bindings: from
package/umt_wasm,bun run gen(orcargo run --manifest-path codegen/Cargo.tomlthencargo fmt). - Do not edit
src/generated.rsordoc/generated.mdby hand. After changingumt_rustpublicumt_*functions, regenerate and commit both files. - Codegen only considers
pub fn umt_*. Modules that omit the prefix (currentlyumt_rust::ip) are invisible — they are neither generated nor listed as skipped. - Functions whose signatures are not wasm-bindgen-friendly (
DateTime<Utc>, custom enums, generics, closures) are listed as skipped indoc/generated.md. Hand-written adapters go insrc/manual.rs. - CI:
.github/workflows/wasm-plugin-ci.ymlincludes acodegen-syncjob that fails if generated files drift. Build and test run with cargo / bun; Nix is not used.
Package: umt_go (Go)
Located in package/umt_go. Partial port. Module path github.com/riya-amemiya/umt-go; import github.com/riya-amemiya/umt-go/src/<pkg> (for example src/math, src/ip). Go 1.24.1. No GitHub Actions workflow — run Makefile targets locally.
make test:go test -v -race ./...make fmt/make check/make build- Tests live under
src/tests/<pkg>/and import thesrc/packages. - IP signatures differ from TypeScript:
CidrToLongtakes"network/prefix"and returns[start, end];IsInRange(ip, "network/prefix");GetNetworkAddressreturns a dotted string;LongToIp/CidrToSubnetMaskpanic on invalid input. - Date helpers include
StartOf/EndOf/AddDuration/IsBusinessDay. There is noIsBetween,AddBusinessDays, or unix conversion.
Package: umt_i18n (TypeScript)
Located in package/umt_i18n. Nested-key translator (UMT_i18n), not a port of package/main. npm name umt-i18n. Depends on umt for types only.
- Setup:
bun install - Testing:
bun run test(Jest,src/tests) - Linting:
bun run lint - Placeholders are
{{name}}. Plural suffixes_zero/_one/_otherexcept localesja/zh/ko. Lookup: current → fallback locales → default locale →defaultValueor the key.
Algorithms & Specific Implementations
- String Distance: Implement Levenshtein and similar algorithms using O(min(N, M)) space complexity (two-row strategy).
- Sorting: When sorting lists with
NaN, use a single-pass partition (valid vs. NaN) followed by sorting the valid partition. - Unwrap:
umt_unwrapshould panic with a message onNone/null. - Equality: Custom equality checks should strictly distinguish
1(int) fromTrue(bool).