بنقرة واحدة
project-conventions
Internal dev.tools project conventions — state, styling, contexts, typing, and code style rules
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Internal dev.tools project conventions — state, styling, contexts, typing, and code style rules
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Add or update an app in the dev.tools software installer catalog
Add a prompt or skill to the dev.tools prompts collection (TypeScript catalog workflow)
Add a new tool page to dev.tools — covers ToolView, Editor, and Custom patterns
Scaffold a new tool page in dev.tools following the established pattern
Run the complete dev.tools pre-commit verification pipeline
Extend the LLM VRAM calculator — add quant families, update formulas, add test anchors
| name | project-conventions |
| description | Internal dev.tools project conventions — state, styling, contexts, typing, and code style rules |
Internal reference skill. Not user-invocable. Apply these conventions whenever reading or writing code in this repo.
React Context API only. No Redux, no Zustand, no external state libraries.
The five contexts in src/components/contexts/:
| Context | Import path | Purpose |
|---|---|---|
ThemeContext | @/contexts/ThemeContext | Light/dark theme; persists to localStorage; sets data-theme on <html> |
PageContext | @/contexts/PageContext | Page title (setPageTitle()), About panel visibility (helpVisible, setHelpVisible, setHasToolAbout) |
ToasterContext | @/contexts/ToasterContext | User feedback toasts |
FileOpenContext | @/contexts/FileOpenContext | File open dialog |
FileSaveDialogContext | @/contexts/FileSaveDialogContext | File save dialog |
Every page component must call setPageTitle inside useEffect:
const { setPageTitle } = usePage();
useEffect(() => {
setPageTitle('My Page Title');
}, [setPageTitle]);
src/styles/.scss file per feature areasrc/styles/colors.scss — use these, do not hardcode hex values| Alias | Resolves to |
|---|---|
@/* | src/* |
@/contexts/* | src/components/contexts/* |
@/controls/* | src/components/controls/* |
@/elements/* | src/components/elements/* |
@/styles/* | src/styles/* |
Always use path aliases for imports that cross feature boundaries.
Shared types live in src/common/types.ts. The key interfaces:
IStringUtil — synchronous tool { toolId, textToDisplay, description?, toolFunction: (input: string) => string }IHashUtil — async tool { toolId, textToDisplay, description?, toolFunction: (input: string) => Promise<string> }UtilList — group of tools { toolGroupId, displayName, utils: IStringUtil[] }Do not redefine these anywhere else. Import from @/common/types.
All tool factory functions (createXxxUtils(), createXxxUtilList()) live in src/common/utils-factory.ts. Page components import from there — never define tool arrays inline in a page component.
package.json){
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "consistent",
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "always",
"objectWrap": "collapse",
"proseWrap": "preserve",
"plugins": ["prettier-plugin-organize-imports"]
}
PostToolUse hook auto-runs Prettier on every edit — do not fight the formatter.
Write no comments by default. Only add one when the WHY is non-obvious: a hidden constraint, a subtle invariant, or a workaround for a specific bug. Do not document WHAT the code does.
Every tool page that has an "About this tool" collapsible panel must mount <ToolAbout>:
import ToolAbout from '@/controls/ToolAbout';
// Inside the page JSX, above <ToolView>:
<ToolAbout routeKey="my-tool">One-paragraph description shown when the user opens the About panel.</ToolAbout>;
routeKey — kebab-case route identifier; used as the localStorage key toolAbout:<routeKey>.localStorage automatically; default is false (hidden).ToolAbout is mounted (controlled via setHasToolAbout).ToolAbout to pages that have no meaningful description to show.Use for Monaco-left + rendered-preview-right layouts (Markdown, Mermaid, HTML tools).
import SplitPreviewEditor from '../../components/elements/editor/SplitPreviewEditor';
<SplitPreviewEditor
language="markdown"
value={content}
onChange={setContent}
renderPreview={(val) => <MyRenderer source={val} />}
editorToolbarChildren={<CopyButton />} // optional
previewToolbarChildren={<ExportButton />} // optional
/>;
The component applies .editorpane, .eh, and .eb CSS primitives from primitives.scss internally — do not wrap it in additional pane divs.
The app builds as a static export (next.config.mjs: output: 'export'). No server-side APIs, no getServerSideProps. Use getStaticProps / getStaticPaths if needed, or client-side data fetching only.
When running Subagent-Driven Development sessions, skip the per-task reviewer dispatch when ALL of the following hold:
Keep per-task reviews when:
Final review: Focus the final whole-branch reviewer on correctness bugs and spec completeness only — not style, formatting, or naming (those are lint/Prettier's job). Skip Minor style findings in the final review dispatch.
Rationale: In T3.2 (Jun 2026), 3 per-task reviews took ~2m 47s and found only Minor style issues (JSX comments, import order — all lint-catchable). The final review caught the actual correctness bug. Per-task reviews add proportional value only on design-judgment tasks.