Skip to content

Latest commit

 

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sting

Sting

Bilbo's blade that glows blue when enemies are near. Detects problems in a FE project.

A fast CLI for static analysis of Typescript project.

Why Sting?

  • Fast - Commands run pretty fast
  • Static analysis - Finds issues invisible to linters
  • AI-friendly - Designed for use with AI tools to reduce context

Installation

Cargo

cargo install sting

Script

Use the install.sh script to install in your machine or download the binaries from the releases list.

curl -LSfs https://raw.githubusercontent.com/awork-io/sting/main/install.sh | sh

For more details about this installation script see install.sh -h.

Claude Skill

Install the bundled Sting skill file for Claude:

sting skill install

Install to a specific directory:

sting skill install --path ~/.claude/skills/sting

Install to a specific file path:

sting skill install --path ~/.claude/skills/sting/SKILL.md

Run non-interactively (uses default path ~/.claude/skills/sting/SKILL.md):

sting skill install --yes

Commands

query-all

List all entities (components, services, pipes, directives, workers, etc.) in a project.

sting query-all ./my-project

query

Find a specific entity by name.

sting query ./my-project UserService
sting query ./my-project "Dashboard"

unused

Find entities that are defined but never imported anywhere.

sting unused ./my-project

# Exit non-zero when unused entities are found
sting unused ./my-project --fail-on-findings

Options:

  • --fail-on-findings - Exit with a non-zero status code when unused entities are found

graph

Output the dependency graph as JSON (D3.js compatible format).

# Output full dependency graph
sting graph ./my-project > deps.json

# Filter to specific entity types
sting graph ./my-project --entity-type component
sting graph ./my-project --entity-type component,service,directive,pipe

Options:

  • --entity-type - Filter to specific entity types (comma-separated). See Entity Types for available values.

affected

List affected file paths, one per line, compared to a base reference.

# Basic usage - compare against main branch
sting affected ./my-project --base main

# Include transitive dependencies (multi-hop)
sting affected ./my-project --base main --transitive

# Output only directory paths (useful for test runners)
sting affected ./my-project --base main --paths

# Output full paths to test files
sting affected ./my-project --base main --tests

# Filter by project type (web, mobile, or libs)
sting affected ./my-project --base main --project web
sting affected ./my-project --base main --project libs --tests

# Show the detailed human-readable summary
sting affected ./my-project --base main --summary

Options:

  • --base - Git reference to compare against (branch, tag, or commit SHA)
  • --transitive - Include transitive consumers (multi-hop dependency traversal)
  • --paths - Output only unique directory paths (without filenames)
  • --tests - Output full paths to test files related to affected entities
  • --summary - Output the detailed human-readable summary
  • --project - Filter results by project type: web, mobile, or libs

chain

Find the dependency chain between two entities. Useful for understanding how components are connected.

# Find all paths from UserService to ApiClient
sting chain ./my-project --start UserService --end ApiClient

# Find only the shortest path
sting chain ./my-project --start UserService --end ApiClient --shortest

# Limit the number of paths returned
sting chain ./my-project --start UserService --end ApiClient --max-paths 10

# Limit the search depth
sting chain ./my-project --start UserService --end ApiClient --max-depth 5

Options:

  • --start - Starting entity name
  • --end - Ending entity name
  • --shortest - Only return the shortest path (default: return all paths)
  • --max-paths - Maximum number of paths to return (default: 100)
  • --max-depth - Maximum path depth/length to explore (default: 10)

cycles

Detect circular dependencies in the project.

# Find circular dependencies
sting cycles ./my-project

# Limit the number of cycles reported
sting cycles ./my-project --max-cycles 50

# Limit the maximum cycle length to detect
sting cycles ./my-project --max-depth 5

Options:

  • --max-cycles - Maximum number of cycles to report (default: 100)
  • --max-depth - Maximum cycle length to detect (default: 10)

rank

Rank entities by various metrics. Useful for identifying components with the most or fewest dependencies.

# Rank all entities by dependency count (least to most)
sting rank ./my-project --by deps

# Rank only components
sting rank ./my-project --by deps --entity-type component

# Rank services and directives
sting rank ./my-project --by deps --entity-type service,directive

Output format (tab-separated):

0	SimpleComponent	component	/path/to/simple.component.ts
1	ButtonComponent	component	/path/to/button.component.ts
3	FormComponent	component	/path/to/form.component.ts

Options:

  • --by - What to rank by. Currently supports: deps (dependency count)
  • --entity-type - Filter to specific entity types (comma-separated). See Entity Types for available values.

mem-leaks

Detect potential memory leak risks with static analysis, grouped by entity.

# Analyze all entity types
sting mem-leaks ./my-project

# Filter to components and services
sting mem-leaks ./my-project --entity-type component,service

# Limit detailed findings shown per entity
sting mem-leaks ./my-project --max-findings 3

# Strict mode keeps take(1), first(), and last() subscriptions as potential leaks
sting mem-leaks ./my-project --strict

Output format (tab-separated):

3	high	DashboardComponent	component	/path/to/dashboard.component.ts

Current rule behavior:

  • RxJS subscriptions without cleanup are reported, with conservative suppression for proven cleanup patterns
  • take(1), first(), and last() subscriptions are treated as finite and are not reported as leaks by default
  • --strict keeps take(1), first(), and last() subscriptions as potential leaks
  • --strict also reports setTimeout without clearTimeout
  • Other finite RxJS operators like single() and takeWhile() are still treated as potential leak risk
  • @AutoUnsubscribe(...) suppresses only subscriptions that are provably tracked by the decorator config
  • API-call subscriptions are suppressed (for example service/API client/HTTP call subscriptions)
  • Timer checks always report setInterval without clearInterval
  • setTimeout without clearTimeout is reported only in --strict mode

Options:

  • --entity-type - Filter to specific entity types (comma-separated). See Entity Types for available values.
  • --max-findings - Maximum number of detailed findings to show per entity (default: 5)
  • --strict - Use stricter RxJS heuristics and keep take(1), first(), and last() subscriptions as potential leaks

affected-mem-leaks

Analyze memory leaks only in affected non-test TypeScript files.

# Analyze affected non-test files compared to origin/develop
sting affected-mem-leaks ./my-project --base origin/develop

# Include transitive consumers in the affected set
sting affected-mem-leaks ./my-project --base origin/develop --transitive

# Scope affected set to web project only
sting affected-mem-leaks ./my-project --base origin/develop --project web

# Strict mode keeps take(1), first(), and last() subscriptions as potential leaks
sting affected-mem-leaks ./my-project --base origin/develop --strict

# Exit non-zero when leak findings are reported
sting affected-mem-leaks ./my-project --base origin/develop --fail-on-findings

Notes:

  • Only non-test files are analyzed (.ts, excluding .spec.ts, .test.ts, .e2e.ts)
  • Output includes total affected non-test file count and a preview of the first 10 files
  • When more than 10 files are analyzed, output includes ...and more (N additional files)
  • Use --fail-on-findings to make this command exit non-zero after printing findings

Options:

  • --base - Git reference to compare against (branch, tag, or commit SHA)
  • --transitive - Include transitive consumers (multi-hop dependency traversal)
  • --project - Filter affected set by project type: web, mobile, or libs
  • --entity-type - Filter leak analysis to specific entity types (comma-separated)
  • --max-findings - Maximum number of detailed findings to show per entity (default: 5)
  • --strict - Use stricter RxJS heuristics and keep take(1), first(), and last() subscriptions as potential leaks
  • --fail-on-findings - Exit with a non-zero status code when leak findings are found

skill install

Install the bundled Claude skill file (skills/sting/SKILL.md) to your machine.

# Interactive prompt for destination path
sting skill install

# Install to a specific directory
sting skill install --path ~/.claude/skills/sting

# Install to a specific file path
sting skill install --path ~/.claude/skills/sting/SKILL.md

# Non-interactive (uses default path)
sting skill install --yes

Options:

  • --path - Destination directory or full file path
  • --yes - Skip prompts and use default path when --path is not provided

Entity Types

Sting detects the following entity types in TypeScript/Angular projects:

Type Description
class Plain classes (no Angular decorator)
component Classes decorated with @Component
service Classes decorated with @Injectable
directive Classes decorated with @Directive
pipe Classes decorated with @Pipe
enum Exported enums
type Exported type aliases
interface Exported interfaces
function Exported functions
const Exported constants
worker Web Workers (.worker.ts files)

Status

Experimental - APIs may change.

Suported

  • Angular app with a NX style monorepo

License

MIT

About

Static code analyzer for FE projects

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages