Imported from TychoQS/kanjime (
AGENTS.md). Install upstream withnpx skills add TychoQS/kanjime. Copyright stays with the author.
AGENTS.md
Source: .requirements/DESIGN_GUIDELINES.csv
Scope: whole repo.
Core Directives
Architecture
- The application must run on both iOS and Android. The code must be designed with the intention of being usable for both platforms and the app design to be executed on phone screens and not on monitors; The data within the application will be passed along using a unidirectional data flow architecture, which is how React is designed to work; Architecture: The application will employ an MVVM (Model-View-ViewModel) architecture using react hooks as viewmodels; The system will be "standalone", that is, the application will work by itself without an internet connection; The project folder architecture will be divided by features, having within it all the folders that are necessary (component, viewmodel, model, view, etc.).
Dependency Injection
- Components, viewmodels or screens should only receive what is strictly necessary as props or context. CompositionRoot should not be passed directly to the screens.
State Management
- All business logic and screen data must reside in the viewmodels and be accessed by the relevant views or screens via a unidirectional data flow.
Model
- To perform the classifications, you must use the inference model in ONNX format included in the project. If the model is not on onnx format, it must be converted to onnx format; The pre-processing workflow for image-based classification is contained in a Python file alongside the model. You should take this and adapt the workflow to run within the web application, in line with the defined technology stack; The classification module will be responsible for preparing the images appropriately (it will convert the canvas images to a black background with white lines and run the other images through the pre-processing pipeline) before passing the image to the classifier. The application should act solely as a client to this module; it will pass the image and relevant information to the module, which will return the list of predictions (already filtered in the case of the canvas); The inference module information is located in
data/modeldirectory.
Technologies
- Tech Stack: Development will be based on web technologies (React + Capacitor + TypeScript); For state management, useContext will be employed; For navigation, a stack-based navigation using React Router and IonRouterOutlet will be employed; The deep learning models will be executed using ONNX Runtime Web; The UI library to be used will be Ionic React, which is designed to work with Capacitor and adapts natively to iOS and Android. Components will be built using Ionic React as a base. Ionic components will be used for navigation, modals, lists, and any element with native mobile behavior. The logic and structure of the components will remain standard React.
Monorepo
- The project must be organized as a monorepo containing the App, the administration panel and the required shared packages.
App And Admin Separation
- The App and the administration panel must remain as independent applications within the monorepo, avoiding mixing screens, routes or application-specific logic between them.
Shared Packages
- Common logic, types and utilities shared by the App and the administration panel must be placed in shared packages, avoiding duplicated definitions between applications.
Admin
- The administration panel must be limited to technical support tasks, such as managing version configuration and consulting errors reported by the App.
Code Conventions
- The naming conventions are: - Components, directories, and files: PascalCase - Functions, variables, and hooks: camelCase - Constants: UPPER_SNAKE_CASE; Regarding formatting, the following rules will be defined in Prettier: - Double quotes for strings - Semicolon at the end of instructions - space indentation These will be defined in the corresponding Prettier file to ensure their follow-up; Regarding syntax, the following rules are established: -The reserved word any cannot be used - Unused variables, functions, components, and others are not allowed - console.log cannot be used in the final code These will be defined in the corresponding ESLint file to ensure their operation; All text generated in an artifact (code, documentation, etc...) must be strictly in English. The only exception is the internationalization files, which will be in the corresponding language to ensure the same; Hard-coded literals should not be used in either the application or the tests. This data should be provided using variables or constants; Code conventions, formatting, typing, documentation and testing rules must apply to the App, the administration panel and the shared packages.
Contracts
- Contracts must be placed in a folder named ‘Contracts’ within the directory of the relevant Feature; Contracts for the same interface must be consolidated into a single file with the same name.
Documentation
- Documentation must be done with TSDoc for all artifacts; In any interface within the ‘Contracts’ directory, its preconditions, invariants and postconditions must be documented somewhere (in the interface itself, in a method or in an attribute) using the ‘@pre’, ‘@inv’ and ‘@post’ annotations. This does not affect the tests or the rest of the code.
Errors & Logging
- Errors will be handled through the use of Try-Catch statements and by showing a dialog stating that an error has occurred. The text to be displayed must be in natural language and must not use technical terms related to technology or the exception. Instead of "Exception XXX Could not connect with the model", it would indicate "An unexpected error has occurred and the character could not be identified"; Unexpected exceptions must not be swallowed in silent try-catch blocks. If a layer cannot explicitly recover from the error, it must rethrow it up to the ViewModel, which is responsible for converting it into a controlled state and calling the observability service; Only unexpected runtime errors must be reported to observability. Expected validations, controlled precondition failures, empty states, offline recovery, or normal fallbacks must not generate error reports; Helper functions, safe fallbacks, or pure utilities must not call the observability service directly. They must return a controlled result or rethrow the error so the responsible layer can handle it.
Testing
- The initial tests will be generated by the programmer and can be executed by the agent. The agent will be able to create new test files and execute them. The agent cannot read existing test files to guarantee that it does not adapt its implementation to the tests instead of correctly solving the problem. If a test fails, the agent must review its implementation, not the test; The tests generated from DbC contracts must mandatorily cover both the happy path and unhappy paths: preconditions must have tests that violate them; invariants must be verified before and after every operation including those that attempt to break them; postconditions must have tests verifying they do not hold when the operation should not have executed; The testing framework will be: - vitest for unit and integration tests - playwright for end-to-end tests; Each condition (precondition, invariant or postcondition) must have its own unit test. In integration or end-to-end testing, there must be one test per requirement; The stubs used for testing should throw an exception with the text ‘Not implemented yet’ instead of default valu; In end-to-end tests, use
expect.poll()for waiting to prevent race conditions; In end-to-end tests, useexpect().toBeVisible()to ensure that a component is visible, thereby preventing race conditions; The --pass-with-no-tests option is forbidden in any testing script. If a test command finds no tests, it must fail in order to detect incomplete configurations, wrong paths, or missing test inclusion; Excluding test files from testing configuration or scripts to make the suite pass is forbidden. Tests may only be excluded for a justified and documented technical reason; Every added or modified expect must include a descriptive message indicating which requirement, condition, or behavior is being verified; Test fixtures representing domain entities must use the shared types from @kanjime/shared when available. Free-form objects must not be used to represent entities already modeled in the domain; In Ionic components, tests must verify states such as disabled, visibility, or accessibility through Ionic-compatible APIs, exposed properties, aria attributes, or final observable state, avoiding assumptions that the component behaves exactly like native HTML.
Admin
- Administration panel views must be built using Ionic components when a suitable component exists, avoiding raw HTML for lists, forms, cards, buttons, loading states, and error messages.
Data
- The data used to populate the application database will be extracted from KanjiVG, JMDict and Kanjidict2, with the exception of the character data, which will be taken from the text file containing the classification model classes. The relevant attribution and licence information must be provided for these sources; Automated workflows must be set up to download the latest version and regenerate the table for data sources such as JMDict and Kanjidic2, which stipulate this in their terms of use. This will ensure that the process of updating the data used by the application is automated; To ensure adequate performance and standalone operation, Capacitor SQLite will be used so that the application does not have to load all the sources with their unnecessary data. A pre-packaged database must be created within the application’s assets to consolidate the processed data from the sources. The MVVM architecture hooks must be configured to perform efficient SQL queries, ensuring that the database is copied correctly to the device native storage on first launch; The fields will be as follows, extracted from the relevant source and with the properties indicated below: Character: List of model classes (primary key and not null) Radical: Kanjidic2 (not null, must be the classcical radical) Components: KanjiVG Meaning (different languages): Kanjidic2 Kunyomi: Kanjidic2 (will have an index) Kunyomi examples: JMDict Onyomi: Kanjidic2 (will have an index) Onyomi examples: JMDict Number of strokes: Kanjidic2 (not null) Stroke order: KanjiVG (not null) JLPT level: Jonathan Waller's Tanos Joyo level: Kanjidic2; If the application requires additional data to be stored, this will be done using Capacitor SQLite, with the data stored locally to ensure its availability.
UI Rules
Color Design
- The application will never use literals to define colors. For this, it will use global variables, in a way that facilitates the implementation of the visual appearance requirements of the application.
Internationalization
- The application must be multilingual, using i18n functions. Specifically, it must support the following languages: - American English - British English - The languages of the main European countries - The languages of the main Asian countries - The languages of the main African countries.
Kanji Entry
- The kanji entry view must display all available information stored in the database, including character, radical, components, meanings, readings (onyomi and kunyomi), usage examples, stroke count, stroke order, and classification levels. If any field is missing must don't render in the interface.
Search Results
- Each search result must display a summary of the kanji including at least the character, its main readings, and associated levels.
About
- The "About" screen must display relevant application information including version, license, terms of use, authorship, and acknowledgments.
Inference Results
- The classification results list must display predicted characters ordered by confidence without showing numeric values.
Layout
- The interface should be primarily organized in a single vertical column with stacked elements to facilitate scrolling and readability; The most important elements (input, results, primary actions) should have more visual weight than secondary elements; Interaction areas (canvas, image, results list) should be clearly visually separated; There should be consistent spacing between components to avoid visual clutter.
Interaction
- Every user interaction should produce an immediate visual response (e.g., press, loading, selection); Interactive elements must clearly show their state (active, selected, disabled); Interactive elements should be easily identifiable as such (buttons, lists, icons); Navigation actions should behave consistently throughout the application; Lists with content exceeding the visible area must allow vertical scrolling limited to the available content, preventing scrolling beyond content boundaries.
Responsive
- The state of the interface must be preserved when the user rotates the screen; The interface must adapt properly to mobile phones and tablets without losing functionality; Elements such as images or canvas should scale while maintaining proportions and usability; The interface must remain usable and consistent when the device is rotated.
Visual
- Colors must be applied consistently across all UI components; Sufficient contrast must be maintained between text/background and interactive elements to ensure readability; Unnecessary colors or styles that hinder readability or distract the user should be avoided; Recognizable icons (copy, back, close, etc.) should be used to improve usability.
Content
- Important information should be visible without requiring complex interactions; Texts should be clear, simple, and understandable for the user.
Accessibility
- Text and UI elements must be readable across different lighting conditions and screens; Interactive elements must have sufficient size for touch interaction; Visual indicators must exist for important actions (loading, error, selection); When developing UI&UX WCAG guidelines for mobile applications.
Consistency
- The same action should always produce the same result across the application; Components should reuse common visual and interaction patterns; Different screens must maintain visual and structural consistency.
Minimalism
- The interface should avoid unnecessary elements that do not add value; Design should prioritize functionality over decorative elements; Extra steps or screens that do not add value should be avoided.
Feedback
- The application must always inform the user about ongoing processes (loading, processing, idle states); When no data is available (no results, empty history), the interface should clearly communicate it; Error messages must be clear, non-technical, and help the user understand what happened.
Admin
- The administration panel must prioritize a clear and functional structure, organizing technical information into separated sections for versions and errors; The administration panel screens must maintain visual and structural consistency, reusing common patterns for lists, forms, loading states and error messages; The administration panel must avoid features, screens or visual elements that are not related to version configuration or error observability.
