Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Expert skill for designing module systems including resolution algorithms, import/export mechanisms, visibility control, namespace management, and cyclic dependency handling.
.claude/skills/a5c-ai-module-systems/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 121% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 137% | 0% |
| case-21 | ✗→✓ | ▲ Improved | 36% | 0% |
Design and implement module systems for programming languages with support for resolution, loading, visibility, and dependency management.
Invoke this skill when you need to:
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | moduleStyle | string | Yes | Style (es6, commonjs, rust, ml) | | resolutionStrategy | string | Yes | Resolution (node, rust, python, custom) | | features | array | No | Features to implement | | cyclicHandling | string | No | How to handle cycles (error, lazy, tarjan) | | visibility | object | No | Visibility model configuration |
json{ "features": [ "import-export", "re-exports", "namespace-aliasing", "selective-imports", "default-exports", "lazy-loading", "cyclic-detection", "visibility-control", "inline-modules", "package-integration" ] }
module-system/
├── syntax/
│ ├── import.grammar # Import statement syntax
│ ├── export.grammar # Export statement syntax
│ └── module-decl.grammar # Module declaration syntax
├── resolution/
│ ├── resolver.ts # Main resolution algorithm
│ ├── module-graph.ts # Dependency graph
│ ├── path-resolver.ts # Path resolution
│ └── cache.ts # Module cache
├── loading/
│ ├── loader.ts # Module loader
│ ├── lazy-loader.ts # Lazy loading support
│ └── parallel-loader.ts # Parallel loading
├── visibility/
│ ├── access-control.ts # Visibility checking
│ └── namespace.ts # Namespace management
├── analysis/
│ ├── cycle-detector.ts # Cyclic dependency detection
│ └── dependency-analyzer.ts # Dependency analysis
└── tests/
├── resolution.test.ts
├── cycles.test.ts
└── visibility.test.tstypescript// Import syntax import defaultExport from 'module'; import { named, another as alias } from 'module'; import * as namespace from 'module'; // Export syntax export const value = 42; export function func() {} export default class MyClass {} export { name, other as renamed }; export * from 'other-module'; // Implementation interface ESModule { defaultExport?: any; namedExports: Map<string, any>; reExports: ReExport[]; } interface ImportSpecifier { type: 'default' | 'named' | 'namespace'; imported: string; local: string; }
rust// Module declaration mod my_module; // Load from file mod inline { ... } // Inline module // Use statements use crate::module::Item; use super::parent::*; use self::child::Thing; use external_crate::Something; // Visibility pub struct Public; pub(crate) struct CrateVisible; pub(super) struct ParentVisible; struct Private; // default // Implementation interface RustModule { name: string; path: ModulePath; visibility: Visibility; items: Map<string, ModuleItem>; submodules: Map<string, RustModule>; } type Visibility = | { type: 'private' } | { type: 'public' } | { type: 'restricted'; path: ModulePath };
ocaml(* Module signature *) module type STACK = sig type 'a t val empty : 'a t val push : 'a -> 'a t -> 'a t val pop : 'a t -> ('a * 'a t) option end (* Module implementation *) module ListStack : STACK = struct type 'a t = 'a list let empty = [] let push x s = x :: s let pop = function | [] -> None | x :: xs -> Some (x, xs) end (* Functor *) module MakeSet (Ord: ORD) : SET = struct (* ... implementation using Ord.compare *) end
typescriptinterface NodeResolver { resolveModule(specifier: string, from: string): string | null; } function nodeResolve(specifier: string, fromDir: string): string | null { // 1. If specifier is a core module, return it if (isCoreModule(specifier)) return specifier; // 2. If starts with '/' or './', resolve relative if (specifier.startsWith('/') || specifier.startsWith('./') || specifier.startsWith('../')) { return resolveRelative(specifier, fromDir); } // 3. Otherwise, walk up node_modules let dir = fromDir; while (dir !== '/') { const candidate = path.join(dir, 'node_modules', specifier); const resolved = resolvePackage(candidate); if (resolved) return resolved; dir = path.dirname(dir); } return null; } function resolvePackage(pkgPath: string): string | null { // Check package.json exports/main const pkgJson = readPackageJson(pkgPath); if (pkgJson?.exports) { return resolveExports(pkgPath, pkgJson.exports); } if (pkgJson?.main) { return path.join(pkgPath, pkgJson.main); } // Default to index.js return path.join(pkgPath, 'index.js'); }
typescriptinterface RustResolver { resolveUse(usePath: UsePath, currentModule: ModulePath): ResolvedItem; } function rustResolve(usePath: UsePath, current: ModulePath): ResolvedItem { const [first, ...rest] = usePath.segments; // Determine starting point let startModule: RustModule; if (first === 'crate') { startModule = getCrateRoot(); } else if (first === 'super') { startModule = getParentModule(current); } else if (first === 'self') { startModule = getCurrentModule(current); } else if (isExternCrate(first)) { startModule = getExternCrate(first); } else { // Start from current module scope startModule = getCurrentModule(current); rest.unshift(first); } // Resolve path segments let currentItem: ModuleItem = startModule; for (const segment of rest) { currentItem = resolveSegment(currentItem, segment); checkVisibility(currentItem, current); } return currentItem; }
typescript// Tarjan's algorithm for SCC detection function findCycles(graph: ModuleGraph): ModuleCycle[] { const index = new Map<Module, number>(); const lowlink = new Map<Module, number>(); const onStack = new Set<Module>(); const stack: Module[] = []; const sccs: Module[][] = []; let currentIndex = 0; function strongconnect(module: Module): void { index.set(module, currentIndex); lowlink.set(module, currentIndex); currentIndex++; stack.push(module); onStack.add(module); for (const dep of module.dependencies) { if (!index.has(dep)) { strongconnect(dep); lowlink.set(module, Math.min(lowlink.get(module)!, lowlink.get(dep)!)); } else if (onStack.has(dep)) { lowlink.set(module, Math.min(lowlink.get(module)!, index.get(dep)!)); } } if (lowlink.get(module) === index.get(module)) { const scc: Module[] = []; let w: Module; do { w = stack.pop()!; onStack.delete(w); scc.push(w); } while (w !== module); if (scc.length > 1) { sccs.push(scc); } } } for (const module of graph.modules) { if (!index.has(module)) { strongconnect(module); } } return sccs.map(modules => ({ modules, edges: findCycleEdges(modules) })); }
typescriptinterface VisibilityChecker { canAccess(item: ModuleItem, fromModule: ModulePath): boolean; } function checkVisibility( item: ModuleItem, fromModule: ModulePath, itemModule: ModulePath ): boolean { switch (item.visibility.type) { case 'public': return true; case 'private': return isSameModule(fromModule, itemModule); case 'crate': return isSameCrate(fromModule, itemModule); case 'super': return isParentOrSame(getParent(itemModule), fromModule); case 'restricted': return isDescendantOf(fromModule, item.visibility.path); default: return false; } }
typescriptinterface LazyModule { path: string; loaded: boolean; exports: Map<string, any> | null; loading: Promise<void> | null; } class LazyModuleLoader { private modules = new Map<string, LazyModule>(); async import(specifier: string): Promise<any> { const resolved = this.resolve(specifier); let module = this.modules.get(resolved); if (!module) { module = { path: resolved, loaded: false, exports: null, loading: null }; this.modules.set(resolved, module); } if (module.loaded) { return module.exports; } if (module.loading) { await module.loading; return module.exports; } module.loading = this.loadModule(module); await module.loading; return module.exports; } private async loadModule(module: LazyModule): Promise<void> { const source = await readFile(module.path); const compiled = compile(source); module.exports = await execute(compiled); module.loaded = true; } }
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 37,680 | 62,155 | +65% | 1 | 1 | 0% | 8,273 | 11,194 | +35% | 0 | 0 | — |
case-02 | fail→pass | 38,411 | 36,409 | -5% | 1 | 1 | 0% | 8,263 | 11,184 | +35% | 0 | 0 | — |
case-03 | fail→pass | 45,188 | 37,505 | -17% | 1 | 1 | 0% | 8,259 | 11,180 | +35% | 0 | 0 | — |
case-04 | pass→pass | 22,176 | 20,409 | -8% | 1 | 1 | 0% | 4,168 | 6,978 | +67% | 0 | 0 | — |
case-05 | pass→pass | 15,886 | 16,147 | +2% | 1 | 1 | 0% | 2,507 | 5,622 | +124% | 0 | 0 | — |
case-06 | pass→pass | 16,169 | 15,854 | -2% | 1 | 1 | 0% | 2,899 | 5,830 | +101% | 0 | 0 | — |
case-07 | pass→pass | 15,850 | 16,808 | +6% | 1 | 1 | 0% | 2,463 | 5,647 | +129% | 0 | 0 | — |
case-08 | pass→fail | 17,818 | 24,690 | +39% | 1 | 1 | 0% | 3,171 | 7,509 | +137% | 0 | 0 | — |
case-09 | fail→pass | 18,556 | 18,525 | -0% | 1 | 1 | 0% | 3,003 | 6,643 | +121% | 0 | 0 | — |
case-10 | pass→pass | 11,912 | 10,764 | -10% | 1 | 1 | 0% | 2,202 | 4,681 | +113% | 0 | 0 | — |
case-11 | pass→pass | 14,847 | 16,871 | +14% | 1 | 1 | 0% | 2,631 | 5,893 | +124% | 0 | 0 | — |
case-12 | pass→pass | 15,314 | 17,632 | +15% | 1 | 1 | 0% | 3,015 | 6,178 | +105% | 0 | 0 | — |
case-13 | fail→pass | 16,523 | 18,790 | +14% | 1 | 1 | 0% | 2,714 | 6,445 | +137% | 0 | 0 | — |
case-14 | pass→pass | 18,750 | 14,770 | -21% | 1 | 1 | 0% | 2,735 | 5,362 | +96% | 0 | 0 | — |
case-15 | pass→pass | 20,879 | 21,363 | +2% | 1 | 1 | 0% | 3,298 | 6,081 | +84% | 0 | 0 | — |
case-16 | pass→pass | 16,716 | 32,299 | +93% | 1 | 1 | 0% | 2,875 | 7,940 | +176% | 0 | 0 | — |
case-17 | pass→pass | 17,941 | 17,490 | -3% | 1 | 1 | 0% | 3,248 | 6,265 | +93% | 0 | 0 | — |
case-18 | pass→pass | 17,787 | 22,352 | +26% | 1 | 1 | 0% | 2,820 | 6,805 | +141% | 0 | 0 | — |
case-19 | pass→pass | 12,219 | 16,806 | +38% | 1 | 1 | 0% | 2,106 | 5,345 | +154% | 0 | 0 | — |
case-20 | fail→fail | 49,411 | 40,569 | -18% | 1 | 1 | 0% | 8,216 | 11,137 | +36% | 0 | 0 | — |
case-21 | fail→pass | 40,367 | 35,814 | -11% | 1 | 1 | 0% | 8,217 | 11,138 | +36% | 0 | 0 | — |
case-22 | pass→pass | 20,249 | 25,873 | +28% | 1 | 1 | 0% | 4,245 | 8,834 | +108% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.