AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Module Organisation

skill-techymt-claude-code-superpowers-module-organisation · by TechyMT

|

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add skill-techymt-claude-code-superpowers-module-organisation

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-techymt-claude-code-superpowers-module-organisation)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Module Organisation? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Module Organisation

The pattern

Claude Code organizes code by responsibility, not by feature. Each top-level directory under src/ owns a specific layer of the system. Tools live in tools/, each in its own subdirectory named [Name]Tool/. Commands live in commands/, each in its own subdirectory or file. Business logic lives in services/. AppState lives in state/. React hooks live in hooks/. React components (TUI rendering) live in components/. Pure utility functions live in utils/.

The rule: a tool knows how to execute a capability. A service knows how to coordinate across multiple tools or external systems. A component knows how to render state. A hook knows how to subscribe to state. These never cross — a tool does not render, a component does not call a bash command.

Why this matters

Claude Code is a React application running in a terminal. It has the full complexity of a web app (UI state, async data, event handling) plus the additional complexity of a capability system (tools, permissions, streaming). Without strict layer separation, service logic leaks into components, rendering logic leaks into tools, and state management becomes implicit.

The per-tool subdirectory pattern (tools/BashTool/BashTool.tsx) is intentional: each tool is large enough to warrant its own namespace. BashTool.tsx uses .tsx because bash output can be rendered as JSX in the TUI. FileReadTool.ts uses .ts because its output is plain data. The file extension signals whether the tool has UI concerns.

How to apply it

  1. New capability (file operation, shell command, web request, subagent): create src/tools/[Name]Tool/[Name]Tool.ts[x]. Export the tool as a named constant. Register it in src/tools.ts.
  2. New user command (/something): create src/commands/something/index.ts or src/commands/something.ts. Register it in src/commands.ts.
  3. New external service integration (API client, MCP adapter): create src/services/[name]/. Keep all HTTP/socket code here.
  4. New AppState field: add it to AppStateStore.ts's AppState type. Add it to initialState. Expose a selector in state/selectors.ts.
  5. New React hook (subscribes to state, calls an API): create src/hooks/use[Name].ts.
  6. New UI component (renders in the terminal): create src/components/[Name].tsx.
  7. Pure utility (string manipulation, path normalization, type guards): create src/utils/[name].ts. No side effects, no imports from state/ or tools/.

In the source

src/
├── tools/                    # Capabilities: each is a Tool
│   ├── BashTool/
│   │   ├── BashTool.tsx      # .tsx: renders bash output as JSX
│   │   ├── bashPermissions.ts
│   │   └── bashUtils.ts
│   ├── FileReadTool/
│   │   └── FileReadTool.ts   # .ts: plain data, no rendering
│   ├── AgentTool/
│   │   └── AgentTool.tsx     # Spawns subagents — has UI progress
│   └── GlobTool/
│       └── GlobTool.ts
│
├── commands/                 # User slash commands: /commit, /add-dir, /plan
│   ├── commit.ts             # Simple command: single file
│   ├── config/               # Complex command: subdirectory
│   │   ├── index.ts
│   │   └── configHelpers.ts
│   └── add-dir/
│       └── index.ts
│
├── services/                 # Cross-cutting business logic
│   ├── api/                  # Claude API client
│   ├── mcp/                  # Model Context Protocol
│   ├── compact/              # Message compaction algorithm
│   ├── tools/                # Tool orchestration (not tool implementations)
│   │   └── toolOrchestration.ts
│   └── analytics/
│
├── state/                    # AppState: single source of truth
│   ├── AppStateStore.ts      # Type + initial state (700 lines)
│   ├── AppState.tsx          # React provider
│   ├── store.ts              # Zustand factory
│   └── selectors.ts
│
├── utils/                    # Pure functions, no side effects
│   ├── messages.ts           # Message normalization pipeline
│   ├── permissions/          # Permission rule matching
│   ├── bash/                 # Bash command parsing
│   └── file.ts               # File path helpers, isENOENT()
│
├── hooks/                    # React hooks (state subscriptions)
│   ├── useCanUseTool.ts
│   └── useSettingsChange.ts
│
└── components/               # TUI components (Ink/React)
    ├── REPL.tsx
    └── Spinner.tsx

The services/tools/ directory is distinct from tools/ — it contains the orchestration logic (scheduling, concurrency, budgeting) that runs tools, not the tool implementations themselves. This prevents tools from knowing about their own scheduling.

Apply it to your code

Before — new capability added directly to the query loop:

// src/query.ts — wrong: capability logic polluting the message loop
async function handleToolCall(toolName: string, input: unknown) {
  if (toolName === 'search_logs') {
    // 50 lines of log-searching logic inline here
    const logs = await readLogsFromDisk(input.path)
    return { content: formatLogs(logs) }
  }
  // ...
}

After — capability in the correct location:

// src/tools/SearchLogsTool/SearchLogsTool.ts
export const SearchLogsTool: Tool = {
  inputSchema,
  isConcurrencySafe: (_input) => true,
  isReadOnly: (_input) => true,
  async call(args, context, canUseTool) { /* ... */ },
  async description(input) { return `Search logs in ${input.path}` },
}

// src/tools.ts — register it
import { SearchLogsTool } from './tools/SearchLogsTool/SearchLogsTool.js'
export const getTools = (): Tools => [
  // ...existing tools...
  SearchLogsTool,
]

Signals that you need this pattern

  • Business logic (HTTP calls, file parsing, permission checks) exists directly in a React component
  • A tool imports from state/AppStateStore.ts directly instead of receiving context
  • A utility function in utils/ has side effects or imports from tools/
  • Commands that need access to multiple tools wire them up themselves instead of using the tool registry
  • A new feature adds a file to src/ root instead of the correct subdirectory

Signals that you're over-applying it

  • A single-function utility doesn't need its own subdirectory — a file in utils/ is fine
  • If a tool helper is used only by that tool, keep it in the same subdirectory; don't move it to utils/
  • Not every tool needs a .tsx extension — only use it if the tool's output is rendered as JSX

Works with

  • domain-model — explains the six concepts that map to these directories
  • tool-definition — the Tool interface all tools in tools/ implement
  • naming-conventions — file and export naming within each module

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.