Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pi-structured

Semantic code editing for pi — replace text-based read/edit/write/grep tools with LSP-backed symbol-level tools for TypeScript projects.

Instead of the agent searching through files with rg and reading large file chunks, it navigates a structured code map and edits individual symbols. Imports are auto-resolved. File paths are never exposed.

Quick Start

# Load the extension in any pi session
pi -e ~/dev/pi-structured/src/index.ts

# Or scaffold a new project first
mkdir my-api && cd my-api
pi -e ~/dev/pi-structured/src/index.ts
# Then type: /scaffold:express-api

The extension auto-detects pi-structured projects (by .pi-structured marker or src/{functions,classes,types,...} layout). In non-structured projects, tools are registered but session features don't activate.

How It Works

The agent receives a code map at session start — a structural overview of every exported symbol, organized by kind. All edits go through semantic tools:

Instead of:               Use:
─────────────────────────────────────────
read src/functions/foo.ts  get_symbol("foo")
edit a source file          update_symbol("foo", newBody)
write a new file            create_symbol("foo", "function", body)
grep for code               find_symbol("query")
manage imports              (auto-resolved — no tool needed)

The agent never sees file paths. It thinks and plans in symbol-space only.

Tools

Tool Description
code_map() Structural overview of all symbols, data model, impact analysis
find_symbol("query") Search symbols by name (prefix/substring)
get_symbol("name") Read full body + auto-resolved imports + reference count
create_symbol(name, kind, body) Create symbol — imports auto-detected from body
update_symbol(name, newBody) Replace body — new imports auto-added
delete_symbol(name) Remove symbol, report remaining references
get_references("name") Find all usages via TypeScript LanguageService
typecheck() Run tsc --noEmit diagnostics
add_dependency("pkg") npm install + returns version
plan({ goal, steps }) Declare structured plan with progress tracking
batch([...]) Multiple create/update/delete in one call
manage_imports(name, imports) Manually set imports (rarely needed — auto-imports handles it)

Scaffold Commands

Command Creates
/scaffold:express-api Express + TypeScript REST API
/scaffold:web-app React + Vite + TypeScript frontend
/scaffold:cli CLI tool
/scaffold:library npm package/library
/scaffold:vitest Add Vitest testing to existing project
/scaffold List available scaffolds

All scaffolds create the directory layout, package.json, tsconfig.json, initial barrel, run npm install, and git init + commit.

Project Layout

my-project/
├── .pi-structured              # Marker file
├── tsconfig.json
├── package.json
└── src/
    ├── index.ts                # Barrel — auto-regenerated
    ├── functions/              # export function ... (one per file)
    ├── classes/                # export class ... (one per file)
    ├── interfaces/             # export interface ... (one per file)
    ├── types/                  # export type ... (one per file)
    ├── enums/                  # export enum ... (one per file)
    ├── consts/                 # export const ... (one per file)
    ├── components/             # React components (one per file)
    └── __tests__/              # Mirrors src/ structure

Rules enforced:

  • One exported symbol per file (private helpers allowed)
  • All imports go through the barrel (../index)
  • Raw read/edit/write/grep to symbol directories is blocked
  • bash access to source files triggers a warning
  • Imports are auto-resolved — the agent writes code, the extension handles imports

Features

Auto-imports

The agent writes get_symbol("foo") and references Book, userStore, etc. directly in the body. The extension parses the body, detects external references, resolves them to project symbols or npm packages, and adds the imports automatically.

Impact Analysis

code_map shows how many symbols import each one:

Book — imported by 10 symbols
⚠️  High-impact symbols (modify with care):
  userStore — imported by 12 symbols
  Book — imported by 10 symbols

Plan Tracking

plan({ goal: "Add pagination", steps: [
  { action: "create", symbol: "PaginatedResponse", kind: "type" },
  { action: "update", symbol: "getAllBooks", reason: "add offset/limit" },
]})

Progress is auto-tracked when symbols are created/updated/deleted. Call plan() without arguments to check progress. A widget shows remaining steps.

Batch Operations

batch({ operations: [
  { action: "create", name: "getTags", kind: "function", body: "..." },
  { action: "update", name: "main", body: "..." },
]})

Multiple changes in one turn. Operations run sequentially. Later operations see newly-created symbols.

@symbol References

Users can type fix @lendBook in prompts — the input handler resolves it to get_symbol("lendBook").

Guardrails

  • read/write on symbol files → ⛔ BLOCKED with redirect message
  • edit on symbol files → ⛔ BLOCKED (built-in edit handles non-symbol files)
  • grep on symbol dirs → ⛔ BLOCKED, suggests find_symbol/get_references
  • bash cat/rm/mv on source files → warning appended to output

Architecture

~/dev/pi-structured/
├── src/
│   ├── index.ts                  # Extension entry — registers tools, events, guards
│   ├── types.ts                  # Shared types
│   ├── services/
│   │   ├── ts-service.ts         # TypeScript LanguageService (findReferences, diagnostics)
│   │   ├── project-detector.ts   # Detect pi-structured projects
│   │   └── code-map.ts           # Generate code map + data model + impact analysis
│   ├── tools/
│   │   ├── code-map.ts           # code_map tool
│   │   ├── find-symbol.ts        # find_symbol tool
│   │   ├── get-symbol.ts         # get_symbol tool
│   │   ├── get-references.ts     # get_references tool
│   │   ├── typecheck.ts          # typecheck tool
│   │   ├── create-symbol.ts      # create_symbol tool
│   │   ├── update-symbol.ts      # update_symbol tool
│   │   ├── delete-symbol.ts      # delete_symbol tool
│   │   ├── manage-imports.ts     # manage_imports tool
│   │   ├── add-dependency.ts     # add_dependency tool
│   │   ├── plan.ts               # plan tool + progress tracking
│   │   └── batch.ts              # batch tool
│   ├── overrides/
│   │   ├── read.ts               # Read override (blocks symbol dirs)
│   │   └── edit-write.ts         # Write override (blocks symbol dirs)
│   ├── scaffold/
│   │   └── index.ts              # All scaffold commands
│   └── utils/
│       ├── auto-imports.ts       # Body parsing → auto-import resolution
│       ├── barrel.ts             # Barrel file management
│       ├── imports.ts            # Import parsing utilities
│       └── service-refresh.ts    # TS LanguageService lifecycle
├── DESIGN.md                     # Architectural design doc
├── package.json                  # Deps: typescript
└── node_modules/

Dependencies

  • typescript ^5.8 — in-process LanguageService API
  • @earendil-works/pi-coding-agent — provided by pi at runtime
  • typebox — provided by pi at runtime
  • @earendil-works/pi-ai — provided by pi at runtime

Design Decisions

See DESIGN.md for the full rationale, self-review, and implementation history.

About

Semantic code editing for pi — LSP-backed symbol-level tools for TypeScript projects

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages