chore: project skeleton — module contracts, docs plan, GPLv3
This commit is contained in:
commit
a33ed2eb30
20 changed files with 2220 additions and 0 deletions
90
docs/PLAN.md
Normal file
90
docs/PLAN.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# jmove — Product Plan
|
||||
|
||||
## Vision
|
||||
|
||||
The `mv` for source code that never breaks imports: fast, safe (dry-run +
|
||||
atomic rollback), single static Rust binary — usable by humans in a
|
||||
terminal and by AI agents over `--json`, with zero external toolchains.
|
||||
|
||||
## Competitive landscape
|
||||
|
||||
The closest analog is **refac / ai_refac** (github: jav-ed/ai_refac):
|
||||
moves sources and updates imports/paths across the project, aimed at
|
||||
AI agents without an IDE.
|
||||
|
||||
| | refac/ai_refac | jmove |
|
||||
|---|---|---|
|
||||
| Languages | TS/JS (ts-morph+Bun), Python (Rope), Rust (rust-analyzer LSP), Go (gopls), Dart, Markdown | TS/JS → Java → Python/Go |
|
||||
| Under the hood | spawns external toolchains/LSPs per run | pure Rust, tree-sitter grammars in-process |
|
||||
| Dry-run | **none** — writes straight to disk | core feature, unified diff |
|
||||
| Atomicity/rollback | not described | rewrite-then-move, rollback on failure |
|
||||
| TS limit | 30 files per call | none (index-based) |
|
||||
| Go behaviour | moves whole package for any file | per-file moves |
|
||||
| Java | not supported, not planned | **open niche — headline feature** |
|
||||
| UX | agent-oriented CLI | human UX + first-class `--json` agent mode |
|
||||
|
||||
**Conclusion:** the idea is validated, the product is not. jmove wins on
|
||||
dry-run, speed (no LSP startup), human UX, single-binary distribution,
|
||||
the `split` command (nobody has it) and Java.
|
||||
|
||||
## Why Java is the wedge
|
||||
|
||||
Java imports are fully-qualified package paths hard-coupled to directory
|
||||
layout:
|
||||
|
||||
```
|
||||
src/com/example/utils/Parser.java
|
||||
→ package com.example.utils; // must change
|
||||
→ import com.example.utils.Parser; // must change in every importer
|
||||
→ + physical file move
|
||||
```
|
||||
|
||||
Three coordinated edits per move; outside IntelliJ nobody automates it.
|
||||
In headless/CI/agent contexts there is no IntelliJ. Implementation:
|
||||
tree-sitter Java grammar (mature) + directory⇄package convention +
|
||||
source-root detection (`src/main/java`, `src/`, ...). This is the feature
|
||||
that makes jmove *the* answer for "move a Java file in CI".
|
||||
|
||||
## AI-agent design
|
||||
|
||||
Existing tools ship a raw `.agents/skills/` folder; we do it properly:
|
||||
|
||||
- `--json` on every command. Envelope:
|
||||
`{ "status": "ok" | "dry_run" | "error", "operation": "...", ... }`
|
||||
- Stable error codes + actionable hints:
|
||||
`{ "status":"error", "code":"TARGET_EXISTS", "message":"...", "hint":"Use --force or choose another target" }`
|
||||
- `mv --dry-run --json` → `{ would_move, would_update, affected_files }`
|
||||
so agents preview → confirm → apply → `check --json`.
|
||||
- Exit codes: `0` ok · `1` error · `2` broken imports (from `check`).
|
||||
- `docs/SKILL.md` — machine-readable instructions an agent can drop into
|
||||
context: short, no fluff, workflow-first.
|
||||
|
||||
## Correctness principles
|
||||
|
||||
1. Rewrite **only the specifier string** (byte span), never reformat the
|
||||
statement — no formatter dependency, minimal diffs.
|
||||
2. Resolution must match the language's own lookup: TS extension guessing
|
||||
+ `index.*`; Java package⇄path; (Phase 2) tsconfig `paths` aliases.
|
||||
3. Imports are rewritten **before** the move; any error rolls back all
|
||||
writes. Prefer `git mv` when inside a repo to preserve history.
|
||||
4. Beyond imports, warn (don't silently rewrite) about other references:
|
||||
`package.json` exports, jest mocks, `tsconfig` includes, markdown links.
|
||||
|
||||
## Phases
|
||||
|
||||
- **Phase 1 (MVP)** — as in `todo.md`: TS/JS scan+index, graph, mv with
|
||||
dry-run/atomic apply. Add to MVP: relative-path resolution incl.
|
||||
`index.*` (without it the tool is toy-grade); `check` as the self-test.
|
||||
- **Phase 1.5 — Java.** The differentiator, as soon as the TS pipeline is
|
||||
proven. Also: `--json` + SKILL.md ship *with* Java, not after.
|
||||
- **Phase 2** — disk index cache (`.jmove/`), incremental reindex,
|
||||
tsconfig paths, rayon parallelism, `--git` integration.
|
||||
- **Phase 3** — Python, Go (per-file, unlike refac), `split` command.
|
||||
- **Later** — LSP server mode (become the thing refac spawns), watch mode,
|
||||
VS Code wrapper.
|
||||
|
||||
## Rules (binding, see todo.md)
|
||||
|
||||
KISS · DRY · SOLID · ≤250 lines/file · ≤4 files/folder · fmt+clippy
|
||||
`-D warnings` per commit · no dead code, no `#[allow(dead_code)]` ·
|
||||
English Javadoc-style comments on all public API.
|
||||
59
docs/SKILL.md
Normal file
59
docs/SKILL.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# jmove skill (for AI agents)
|
||||
|
||||
## What this tool does
|
||||
|
||||
Moves or renames source files inside a project and updates every import
|
||||
statement referencing them. Never breaks imports. Supported: TypeScript,
|
||||
JavaScript; Java/Python/Go on the roadmap. Single binary, no LSP needed.
|
||||
|
||||
## When to use
|
||||
|
||||
- The user asks to move/rename/reorganize source files or packages.
|
||||
- You refactored a directory layout and imports now point at nothing.
|
||||
- You need to verify the project has no broken imports (`check`).
|
||||
|
||||
## Commands
|
||||
|
||||
### mv — move a file and rewrite its importers
|
||||
|
||||
```
|
||||
jmove mv <source> <target> [--root DIR] [--dry-run] [--json] [--force]
|
||||
```
|
||||
|
||||
Always run `--dry-run` first and confirm the change set looks right.
|
||||
|
||||
### check — find broken imports
|
||||
|
||||
```
|
||||
jmove check [--root DIR] [--json]
|
||||
```
|
||||
|
||||
Run after any move (or any edit) to validate project consistency.
|
||||
|
||||
## Recommended agent workflow
|
||||
|
||||
1. `jmove mv <src> <target> --dry-run --json` — preview.
|
||||
2. Inspect `affected_files`; if unexpected, abort and ask the user.
|
||||
3. `jmove mv <src> <target> --json` — apply (atomic, rolls back on error).
|
||||
4. `jmove check --json` — verify nothing is broken.
|
||||
|
||||
## Output format (--json)
|
||||
|
||||
Every response: `{ "status": "ok" | "dry_run" | "error", "operation": "...", ... }`.
|
||||
Errors carry a stable `code` (`TARGET_EXISTS`, `SOURCE_NOT_FOUND`, ...)
|
||||
and a `hint` describing the next action. On success, `mv` reports
|
||||
`changed_files` with line-level `old`/`new` import diffs and counters
|
||||
(`moved`, `updated_imports`).
|
||||
|
||||
## Exit codes
|
||||
|
||||
- `0` — success
|
||||
- `1` — operation failed (read `--json` error or stderr)
|
||||
- `2` — `check` found broken imports
|
||||
|
||||
## Rules of use
|
||||
|
||||
- Never run `mv` without a prior `--dry-run` in the same session.
|
||||
- Never pass `--force` unless the user explicitly authorized overwriting.
|
||||
- After every successful `mv`, run `check`; treat exit code `2` as
|
||||
a failed refactor.
|
||||
Loading…
Add table
Add a link
Reference in a new issue