Skip to main content

fractal-file-structuring

Use when creating, moving, splitting, or organizing TypeScript files and folders. Applies fractal tree file-structuring rules which reduce the cognitive overhead of choosing where to put files and ultimately navigating a codebase (once the structure is established and understood).

معلومات المصدر

المستودع
hashintel/hash
آخر نشاط في المصدر
١ سبتمبر ٢٠٢٦ في ٠٧:٥٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٬٦٦٦
التفرعات
١٢٣

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
fractal-file-structuring
description
Use when creating, moving, splitting, or organizing TypeScript files and folders. Applies fractal tree file-structuring rules which reduce the cognitive overhead of choosing where to put files and ultimately navigating a codebase (once the structure is established and understood).
license
MIT
metadata
{"triggers":{"type":"domain","enforcement":"suggest","priority":"high","keywords":["TypeScript","JavaScript","file structure","folder structure","create file","create folder","split file","shared folder"],"intent-patterns":["\\b(create|add|move|split|organize|refactor)\\b.*?\\b(file|folder|directory|module|component|hook|type|helper)\\b","\\b(file|folder|directory)\\b.*?\\b(structure|layout|organization|placement)\\b"]}}
# Fractal File Structuring TypeScript and JavaScript files should be organised in a fractal tree structure. Use this skill when deciding where to create, move, split, or organize files and folders in a TypeScript or JavaScript workspace. This guidance is based on HASH's file-structuring approach: https://hash.dev/blog/file-structuring ## Scope Apply this skill to TypeScript and JavaScript source files, including modules, components, hooks, helpers, types, tests, scripts, and entry points. ## Core Rules ### Use kebab-case names Use kebab-case for all TypeScript and JavaScript file and folder names. ```text create-worker-factory.ts playback-settings-menu.tsx button.tsx ``` Avoid PascalCase, camelCase, and mixed-case file names, even for React components. ### Do not create index files Do not add `index.ts`, `index.tsx`, `index.js`, or `index.jsx` files for folder imports. Prefer explicit file entry points with meaningful names. If a subtree needs a public entry point, name that file after the concept it exposes (e.g. `schema.ts`) ### Treat each file as a mini-library A file should expose one or more named exports with a shared semantic purpose. The file name should summarize that purpose (e.g. `users.ts`) If a file contains only one main export, prefer naming the file after that export in kebab-case (e.g. `create-user.ts`) Avoid default exports unless a framework or external API requires them. ### Split outgrown files into private subtrees When a file becomes too large or contains implementation details worth extracting, create a same-named folder next to it and move private pieces there. ```text editor-view.tsx # public mini-library: the component other files import editor-view/ panels.tsx # private entry point imported by editor-view.tsx panels/ simulate-view.tsx # private to panels.tsx calculate-timeline-range.ts # private helper used only by editor-view.tsx create-panel-state.ts # private helper used only by editor-view.tsx ``` Only `editor-view.tsx` should import from direct child mini-libraries such as `editor-view/panels.tsx` and `editor-view/calculate-timeline-range.ts`. Only `editor-view/panels.tsx` should import from `editor-view/panels/*.tsx`. Other files should import from `editor-view.tsx`, not from its private subtree. This keeps `editor-view.tsx` as the API boundary and makes `editor-view/` read as its implementation. If `editor-view/calculate-timeline-range.ts` grows and needs its own private implementation files, create `editor-view/calculate-timeline-range/`. Only `editor-view/calculate-timeline-range.ts` should import from that deeper subtree. ```text editor-view/ calculate-timeline-range.ts calculate-timeline-range/ clamp-time.ts # private to calculate-timeline-range.ts get-visible-duration.ts # private to calculate-timeline-range.ts ``` ### Keep private subtrees private Do not import directly from another file's implementation folder. ```typescript // Avoid: reaches into another file's private subtree import { SimulateView } from "../editor-view/panels/simulate-view"; // Prefer (1): import from a public mini-library (if it is conceptually part of editor-view) import { EditorView } from "../editor-view"; // Prefer (2): move shared code to a shared folder (if it is NOT conceptually part of editor-view) import { Button } from "../shared/button"; ``` If a resource must be available outside the subtree, re-export it from the subtree root only when it is part of that root's public concept. If it is independently useful to sibling branches, move it to an appropriate `shared/` folder instead. ### Put shared resources at the closest fork When multiple sibling branches need the same helper, type, component, constant, or hook, place it in the nearest applicable `shared/` folder. ```text editor-view.tsx editor-view/ shared/ duration-label.tsx # used by both panels.tsx and bottom-section.tsx playback-time.ts # shared formatting/parsing logic for this subtree panels.tsx # imports from panels/ panels/ simulate-view.tsx # private to panels.tsx bottom-section.tsx # imports from bottom-section/ bottom-section/ bottom-bar.tsx # private to bottom-section.tsx ``` Place shared files as deep as possible while still covering all current consumers. Do not move something to a high-level shared folder just because it might be reused later. Here `editor-view.tsx` imports `./editor-view/panels` and `./editor-view/bottom-section`. `panels.tsx` may import `./panels/simulate-view` and `./shared/duration-label`; `bottom-section.tsx` may import `./bottom-section/bottom-bar` and `./shared/duration-label`. Nothing else should import from `panels/` or `bottom-section/` directly. Shared files are mini-libraries too. A shared file can have its own private same-named subtree, and those internals should remain private to that shared file. ```text editor-view/ shared/ playback-time.ts # public to editor-view/* branches playback-time/ parse-playback-time.ts # private to playback-time.ts format-playback-time.ts # private to playback-time.ts ``` If later only `bottom-bar.tsx` uses `duration-label.tsx`, move it beside `bottom-bar.tsx` or under `bottom-bar/`. The folder structure should describe current consumers, not preserve old sharing. ### Use relative imports within a workspace For imports inside the same workspace, use relative paths. Do not introduce workspace-local aliases just to shorten paths. Imports from other workspaces should use the package name. ### Co-locate unit tests Place unit tests next to the file they cover. ```text foo.ts foo.test.ts ``` If a private extracted file needs direct tests, place those tests next to that extracted file. ```text editor-view.tsx editor-view.test.tsx editor-view/ calculate-timeline-range.ts calculate-timeline-range.test.ts ``` Prefer testing through the public mini-library when that gives enough coverage. Add direct tests for private extracted files when the logic is complex enough that tests through the owner would be indirect or brittle. ### Match the current shape Organize files for the code's current relationships, not speculative future reuse. Moving files later is expected and cheaper than adding premature structure now. ## Decision Checklist Before creating a TypeScript or JavaScript file or folder: 1. Identify the semantic concept the file represents. 2. Name the file or folder in kebab-case. 3. If extracting from an existing file, put private implementation files under a same-named folder. 4. If multiple current branches need the resource, put it in the nearest `shared/` folder. 5. Avoid `index` files and implicit folder imports. 6. Use relative imports within the workspace. 7. Co-locate tests with the file under test. ## When Unsure Choose the location that communicates the file's current consumers and API boundary most clearly: - Private implementation detail: place it under the owning file's same-named folder, and import it only from that owner. - Named mini-library: create a normal named file when the concept has its own purpose and exports a small API for nearby consumers. - Shared mini-library: place the named file in the closest `shared/` folder when multiple branches need that API. - Subtree entry point: expose the public API from a named root file, and keep any deeper implementation files private to that root. Do not add broad `components`, `hooks`, `utils`, `types`, or `services` folders unless absolutely necessary. If they exist, these folders MUST only be imported from by files called `components.ts`, `hooks.ts`, etc.
عرض على GitHub