moonpi 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +431 -0
- package/assets/moonpi-logo.svg +27 -0
- package/assets/screenshots/moonpi-picker.png +0 -0
- package/assets/screenshots/moonpi-startup.png +0 -0
- package/assets/screenshots/moonpi-syn.png +0 -0
- package/assets/screenshots/moonpi-working.png +0 -0
- package/package.json +52 -0
- package/src/config.ts +183 -0
- package/src/context-files.ts +518 -0
- package/src/guards.ts +101 -0
- package/src/index.ts +145 -0
- package/src/modes.ts +233 -0
- package/src/sprint.ts +319 -0
- package/src/state.ts +137 -0
- package/src/synthetic-models.ts +438 -0
- package/src/synthetic.ts +352 -0
- package/src/tools.ts +475 -0
- package/src/types.ts +61 -0
- package/src/ui.ts +84 -0
- package/tsconfig.json +18 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Federico Andrea Galatolo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/moonpi-logo.svg" alt="moonpi" width="520" />
|
|
3
|
+
</p>
|
|
4
|
+
<p align="center"><em>opinionated set of extensions for pi</em></p>
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**moonpi** is set of extensions for [pi](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent) **that are actually useful** for a coding agent.
|
|
9
|
+
No fluff. No over-engineered architecture. Just practical guardrails, structured workflows, and pragmatism.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Opinions
|
|
14
|
+
|
|
15
|
+
moonpi is built around a few **strong opinions**.
|
|
16
|
+
|
|
17
|
+
If these **resonate** with you, you might **find** this set of extensions **useful**:
|
|
18
|
+
|
|
19
|
+
- **Subagents are a waste of tokens.**
|
|
20
|
+
Subagents are useless and just a conspiracy to make us use more tokens.
|
|
21
|
+
*Tin foil hat firmly on.*
|
|
22
|
+
|
|
23
|
+
- **Plan mode is actually useful - but only if history is retained.**
|
|
24
|
+
Plan mode becomes pointless when the model outputs a "plan" and then loses all the context that produced it.
|
|
25
|
+
Planning only works when the planning conversation remains part of the execution context.
|
|
26
|
+
|
|
27
|
+
- **Context is king.**
|
|
28
|
+
Why make the model guess which files matter for a task, wasting tokens and time wandering through the project, when you can inject the relevant files directly into the context?
|
|
29
|
+
Context matters more than models or harnesses, control the context and you control the result.
|
|
30
|
+
|
|
31
|
+
- **Rejecting reads and writes outside the working directory is good steering.**
|
|
32
|
+
Yes, we all know the model can write and execute code, and yes, sandboxing is hard.
|
|
33
|
+
But telling the model "hey, you cannot read that" when it reaches outside the project helps steer behavior.
|
|
34
|
+
May our benevolent AI overlords accept this humble suggestion.
|
|
35
|
+
|
|
36
|
+
- **Read before write is mandatory.**
|
|
37
|
+
If a model tries to overwrite a file without reading it first, that is an error.
|
|
38
|
+
It should not be allowed. Period.
|
|
39
|
+
|
|
40
|
+
- **Prompt cache affinity matters.**
|
|
41
|
+
Switching system prompts or tool definitions between phases destroys the provider's prompt cache, forcing a full re-read of the system prompt on every turn. The phase transition should be invisible to the cache: same prompt, same tool schemas, only runtime behavior changes.
|
|
42
|
+
|
|
43
|
+
- **Loops are stupidly simple.**
|
|
44
|
+
A specification file, a TODO list, and auto-compaction after every phase are more than enough for most use cases.
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
First, install the base `pi` coding agent globally:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install -g @mariozechner/pi-coding-agent
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Then, install the `moonpi` extension set directly via `pi`:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pi install git:github.com/galatolofederico/moonpi@v0.4.1
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## Screenshots
|
|
62
|
+
|
|
63
|
+
<p align="center">
|
|
64
|
+
<img src="assets/screenshots/moonpi-startup.png" alt="moonpi startup with project context notification and mode selector" width="600" />
|
|
65
|
+
<br />
|
|
66
|
+
<em>moonpi startup</em>
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="assets/screenshots/moonpi-picker.png" alt="The /pick file-tree picker for selecting project context files" width="600" />
|
|
71
|
+
<br />
|
|
72
|
+
<em>the /pick file-tree picker</em>
|
|
73
|
+
</p>
|
|
74
|
+
|
|
75
|
+
<p align="center">
|
|
76
|
+
<img src="assets/screenshots/moonpi-working.png" alt="moonpi working on its own codebase" width="600" />
|
|
77
|
+
<br />
|
|
78
|
+
<em>moonpi working on its own codebase</em>
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
## Features
|
|
82
|
+
|
|
83
|
+
moonpi adds a practical workflow layer on top of `pi`, focused on:
|
|
84
|
+
|
|
85
|
+
- explicit work modes
|
|
86
|
+
- persistent planning context with prompt cache retention across phase transitions
|
|
87
|
+
- TODO-driven execution
|
|
88
|
+
- safer file access behavior
|
|
89
|
+
- pickable project documentation context and `/context` inspection
|
|
90
|
+
- sprint-based long-running workflows
|
|
91
|
+
- phase-by-phase execution loops
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## Modes
|
|
95
|
+
|
|
96
|
+
moonpi provides four modes (Auto Mode has two phases):
|
|
97
|
+
|
|
98
|
+
| Mode | Available Tools | Description |
|
|
99
|
+
| --- | --- | --- |
|
|
100
|
+
| **Plan Mode** | `read`, `grep`, `find`, `ls`, `todo`, `question` | Used to reason about the task before making changes. The model must produce a TODO list. No file modifications or shell commands are allowed. |
|
|
101
|
+
| **Act Mode** | `read`, `grep`, `find`, `ls`, `bash`, `edit`, `write`, `todo`, `question` (+ `end_phase` in sprint loop) | Used to execute work. The model can read, write, edit, and run commands. TODO and QnA can be used when helpful, but are not mandatory. |
|
|
102
|
+
| **Auto Mode** (Plan phase) | `read`, `grep`, `find`, `ls`, `todo`, `question`, `end_conversation` | Default mode. The model first plans, then acts while retaining the full planning conversation history. During the planning phase, an `end_conversation` tool is available for question-only requests that do not need a TODO list. |
|
|
103
|
+
| **Auto Mode** (Act phase) | `read`, `grep`, `find`, `ls`, `bash`, `edit`, `write`, `todo`, `question` (+ `end_phase` in sprint loop) | After planning, the model executes the TODO list with full planning context intact. |
|
|
104
|
+
| **Fast Mode** | `read`, `grep`, `find`, `ls`, `bash`, `edit`, `write` (+ `end_phase` in sprint loop) | Direct execution mode. No planning requirement, no TODO list, no QnA. Useful for quick edits and simple tasks. |
|
|
105
|
+
|
|
106
|
+
Modes can be cycled using `Tab`
|
|
107
|
+
|
|
108
|
+
Each mode has a different textbox color in the UI, making the current workflow state immediately visible.
|
|
109
|
+
|
|
110
|
+
## Auto Mode
|
|
111
|
+
|
|
112
|
+
**Auto Mode** is the default moonpi workflow.
|
|
113
|
+
|
|
114
|
+
It works in two phases:
|
|
115
|
+
|
|
116
|
+
1. **Plan phase**
|
|
117
|
+
- editing tools are disabled at runtime (blocked by guards, not removed from the prompt)
|
|
118
|
+
- the TODO list tool is enabled
|
|
119
|
+
- the model plans the work
|
|
120
|
+
- the model either:
|
|
121
|
+
- produces a TODO list, then continues to Act phase
|
|
122
|
+
- or calls `end_conversation` when the user is only asking a question
|
|
123
|
+
|
|
124
|
+
2. **Act phase**
|
|
125
|
+
- editing tools become available (guards no longer block them)
|
|
126
|
+
- the conversation history from the Plan phase is retained
|
|
127
|
+
- the model executes the TODO list with full planning context intact
|
|
128
|
+
|
|
129
|
+
This avoids the "plan then forget everything" problem.
|
|
130
|
+
|
|
131
|
+
### Prompt Cache Retention
|
|
132
|
+
|
|
133
|
+
Auto Mode is specifically designed to preserve the LLM provider's **prompt cache** across the Plan→Act transition. This means:
|
|
134
|
+
|
|
135
|
+
- **Same system prompt.** Both phases use the identical system prompt text. The phase instructions are embedded in a single `AUTO_MODE_PROMPT` that covers both Plan and Act behavior — the prompt never changes between phases.
|
|
136
|
+
- **Same tool schemas.** All moonpi tools (`read`, `grep`, `find`, `ls`, `bash`, `edit`, `write`, `todo`, `question`, `end_conversation`, `end_phase`) are always present in the tool definitions sent to the provider. Tools are never added or removed between phases.
|
|
137
|
+
- **Runtime enforcement only.** In Plan phase, editing tools (`bash`, `write`, `edit`) are blocked by moonpi's runtime guards — the `tool_call` event handler rejects them with an error message. The tool definitions remain in the prompt. When the phase switches to Act, the guards simply stop blocking those tools.
|
|
138
|
+
- **Stable tool schemas for cache.** Even in Fast mode where `todo` is disabled, its JSON schema is still advertised to the provider. This keeps the tool definition block identical across all modes and phases, maximizing cache hits.
|
|
139
|
+
|
|
140
|
+
**Why this matters:** providers cache the system prompt and tool definitions across turns. When the prompt or tool list changes, the cache is invalidated and the entire prefix must be re-processed — costing tokens, money, and latency. By keeping the prompt and tool schemas stable, Auto Mode ensures the cache is retained throughout the entire conversation, from Plan through Act and beyond.
|
|
141
|
+
|
|
142
|
+
## Project Context Picker
|
|
143
|
+
|
|
144
|
+
moonpi injects only the files selected with `/pick` into the model context.
|
|
145
|
+
|
|
146
|
+
### `/pick`
|
|
147
|
+
|
|
148
|
+
Opens a file-tree picker for the current working directory:
|
|
149
|
+
|
|
150
|
+
- `README.md`, `SPECS.md`, and `SPRINT.md` context files are selected by default
|
|
151
|
+
- use `↑` / `↓` to move
|
|
152
|
+
- use `←` / `→` to close and open folders
|
|
153
|
+
- use `Space` to select or deselect files and folders
|
|
154
|
+
- selecting a folder recursively selects **all** descendant files that match the pickable extensions filter
|
|
155
|
+
- selecting a folder with all descendants already selected will deselect them all
|
|
156
|
+
- use `D` to deselect everything
|
|
157
|
+
- use `Enter` to confirm and close the picker
|
|
158
|
+
|
|
159
|
+
The picker only shows files with pickable extensions (code, text, config, and documentation files). Binary files, images, lock files, and other non-text files are hidden. The extension filter is configurable via `pickableExtensions` (see [Configuration](#configuration)).
|
|
160
|
+
|
|
161
|
+
### `/context`
|
|
162
|
+
|
|
163
|
+
Shows which files are currently selected for prompt injection and whether they were auto-discovered at startup or manually selected via `/pick`.
|
|
164
|
+
|
|
165
|
+
Example output:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
3 file(s) auto-discovered (use /pick to change):
|
|
169
|
+
README.md
|
|
170
|
+
SPECS.md
|
|
171
|
+
SPRINT.md
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
5 file(s) manually selected with /pick:
|
|
176
|
+
README.md
|
|
177
|
+
src/config.ts
|
|
178
|
+
src/context-files.ts
|
|
179
|
+
src/types.ts
|
|
180
|
+
src/modes.ts
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
At startup, a notification shows which files are currently selected for injection.
|
|
184
|
+
|
|
185
|
+
### Configuration
|
|
186
|
+
|
|
187
|
+
Configure `.pi/moonpi.json` (project) or `~/.pi/agent/moonpi.json` (global):
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"defaultMode": "auto",
|
|
192
|
+
"preserveExternalTools": false,
|
|
193
|
+
"customEditor": true,
|
|
194
|
+
"contextFiles": {
|
|
195
|
+
"enabled": true,
|
|
196
|
+
"fileNames": ["README.md", "SPECS.md", "SPRINT.md"],
|
|
197
|
+
"maxTotalBytes": 120000,
|
|
198
|
+
"maxDepth": 4,
|
|
199
|
+
"maxScannedEntries": 10000,
|
|
200
|
+
"maxDefaultFiles": 25,
|
|
201
|
+
"pickableExtensions": [
|
|
202
|
+
".ts", ".js", ".py", ".rs", ".go", ".md", ".json", ".yaml",
|
|
203
|
+
".toml", ".sql", ".html", ".css", "Dockerfile", "Makefile"
|
|
204
|
+
],
|
|
205
|
+
"ignoreDirs": [
|
|
206
|
+
".git", ".svn", ".hg",
|
|
207
|
+
"node_modules", ".next", ".turbo",
|
|
208
|
+
".venv", "venv", "__pycache__",
|
|
209
|
+
"target", "dist", "build", "coverage",
|
|
210
|
+
".env", ".gradle", ".idea", ".vscode"
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
"guards": {
|
|
214
|
+
"cwdOnly": true,
|
|
215
|
+
"allowedPaths": ["~/.pi/agent"],
|
|
216
|
+
"readBeforeWrite": true
|
|
217
|
+
},
|
|
218
|
+
"keybindings": {
|
|
219
|
+
"cycleNext": "tab",
|
|
220
|
+
"cyclePrevious": ""
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### General
|
|
226
|
+
|
|
227
|
+
| Field | Default | Description |
|
|
228
|
+
| --- | --- | --- |
|
|
229
|
+
| `defaultMode` | `"auto"` | Mode used at session start. One of `"plan"`, `"act"`, `"auto"`, `"fast"` |
|
|
230
|
+
| `preserveExternalTools` | `false` | When `true`, tools registered by other extensions are kept alongside moonpi tools when applying mode tool restrictions |
|
|
231
|
+
| `customEditor` | `true` | When `false`, moonpi skips installing its mode-colored editor, preserving editor customizations from other extensions |
|
|
232
|
+
|
|
233
|
+
#### Keybindings
|
|
234
|
+
|
|
235
|
+
| Field | Default | Description |
|
|
236
|
+
| --- | --- | --- |
|
|
237
|
+
| `cycleNext` | `"tab"` | Keybinding to cycle to the next mode when the editor is empty |
|
|
238
|
+
| `cyclePrevious` | `""` (disabled) | Keybinding to cycle to the previous mode when the editor is empty |
|
|
239
|
+
|
|
240
|
+
#### Context files
|
|
241
|
+
|
|
242
|
+
| Field | Default | Description |
|
|
243
|
+
| --- | --- | --- |
|
|
244
|
+
| `enabled` | `true` | Enable or disable context file injection entirely |
|
|
245
|
+
| `fileNames` | `["README.md", "SPECS.md", "SPRINT.md"]` | Filenames auto-discovered at startup (before any `/pick` selection) |
|
|
246
|
+
| `maxTotalBytes` | `120000` | Maximum total bytes injected into the prompt. Files are truncated beyond this limit |
|
|
247
|
+
| `maxDepth` | `4` | Maximum directory depth for **startup auto-discovery only**. The `/pick` picker has no depth limit |
|
|
248
|
+
| `maxScannedEntries` | `10000` | Maximum filesystem entries inspected during any scan (startup or `/pick`). Prevents walking huge trees |
|
|
249
|
+
| `maxDefaultFiles` | `25` | Maximum files selected by auto-discovery. Does not affect `/pick` selections |
|
|
250
|
+
| `pickableExtensions` | *(80+ entries, see defaults)* | File extensions (`.ts`, `.py`) and exact filenames (`Dockerfile`, `Makefile`) shown in `/pick`. Non-matching files are hidden from the picker |
|
|
251
|
+
| `ignoreDirs` | *(40+ entries, see defaults)* | Directory names skipped during both auto-discovery and `/pick`. Covers VCS, language-specific caches, build output, IDE folders, and more |
|
|
252
|
+
|
|
253
|
+
#### Guards
|
|
254
|
+
|
|
255
|
+
| Field | Default | Description |
|
|
256
|
+
| --- | --- | --- |
|
|
257
|
+
| `cwdOnly` | `true` | Reject file access outside the current working directory |
|
|
258
|
+
| `allowedPaths` | `[]` | Directories permitted for **read** access even when `cwdOnly` is enabled. Supports `~` expansion and relative paths (resolved from cwd) |
|
|
259
|
+
| `readBeforeWrite` | `true` | Require the model to read a file before writing or editing it |
|
|
260
|
+
|
|
261
|
+
Recommended tuning for huge monorepos:
|
|
262
|
+
|
|
263
|
+
- lower `maxDepth` to `2` or `3` if READMEs are mostly near the root
|
|
264
|
+
- lower `maxScannedEntries` to cap worst-case startup and per-picker-session scanning latency
|
|
265
|
+
- add generated/vendor folders to `ignoreDirs`
|
|
266
|
+
- narrow `pickableExtensions` to only the file types you care about
|
|
267
|
+
- lower `maxDefaultFiles` if too many READMEs are injected by default
|
|
268
|
+
- set `enabled: false` and use manual `@file` references if you do not want automatic context injection
|
|
269
|
+
|
|
270
|
+
If a scan hits a limit, moonpi shows a warning in startup notifications or `/pick`.
|
|
271
|
+
|
|
272
|
+
The system prompt also instructs the model to keep selected project documents up to date, making `README.md` and `SPECS.md` living project documents instead of abandoned archaeology.
|
|
273
|
+
|
|
274
|
+
## TODO List Tool
|
|
275
|
+
|
|
276
|
+
moonpi includes a TODO list tool that can be updated at any moment.
|
|
277
|
+
|
|
278
|
+
Whenever an item is modified, the current full state of the TODO list is returned to the model.
|
|
279
|
+
|
|
280
|
+
This keeps the agent grounded in the actual progress of the task instead of relying on vibes, memory, or whatever it hallucinated three messages ago.
|
|
281
|
+
|
|
282
|
+
## Filesystem Guardrails
|
|
283
|
+
|
|
284
|
+
moonpi adds practical file access rules.
|
|
285
|
+
|
|
286
|
+
### Stay inside the working directory
|
|
287
|
+
|
|
288
|
+
Reads, writes, and edits outside the current working directory are rejected.
|
|
289
|
+
|
|
290
|
+
This is not presented as magical security theater. It is a behavioral constraint that helps steer the model toward project-scoped work.
|
|
291
|
+
|
|
292
|
+
#### Allowed paths
|
|
293
|
+
|
|
294
|
+
When `cwdOnly` is enabled, you can grant the agent read access to specific directories outside the project via `guards.allowedPaths`. This is useful when the agent needs to read its own documentation, extension files, or shared configs that live outside the working directory.
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"guards": {
|
|
299
|
+
"allowedPaths": [
|
|
300
|
+
"~/.pi/agent",
|
|
301
|
+
"/home/user/Projects"
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Paths support `~` expansion (resolved to home directory) and relative paths (resolved from cwd). Only **read** access is granted for allowed paths - writes and edits are still restricted to the working directory.
|
|
308
|
+
|
|
309
|
+
The setting works in both global (`~/.pi/agent/moonpi.json`) and project-level (`.pi/moonpi.json`) configs.
|
|
310
|
+
|
|
311
|
+
### Read before write
|
|
312
|
+
|
|
313
|
+
moonpi requires the model to read a file before writing to it.
|
|
314
|
+
|
|
315
|
+
If the model tries to write to a file without reading it first, the write tool returns an error.
|
|
316
|
+
|
|
317
|
+
This prevents careless overwrites and forces the agent to inspect the current state of a file before modifying it.
|
|
318
|
+
|
|
319
|
+
## Moonpi loop
|
|
320
|
+
|
|
321
|
+
moonpi includes sprint-oriented loop for larger projects.
|
|
322
|
+
|
|
323
|
+
### `/sprint:init`
|
|
324
|
+
|
|
325
|
+
Creates a new sprint for a larger project.
|
|
326
|
+
|
|
327
|
+
This command asks **one question**: the sprint objective.
|
|
328
|
+
|
|
329
|
+
It then delegates SPRINT.md and TASKS.md creation to the agent, which writes:
|
|
330
|
+
|
|
331
|
+
```txt
|
|
332
|
+
./sprints/<sprint_number>/SPRINT.md
|
|
333
|
+
./sprints/<sprint_number>/TASKS.md
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The sprint is divided into phases.
|
|
337
|
+
|
|
338
|
+
Each phase includes tasks and verification steps that define when the phase is complete.
|
|
339
|
+
|
|
340
|
+
The goal is to turn a vague big project into a concrete, phased execution plan.
|
|
341
|
+
|
|
342
|
+
### `/sprint:loop`
|
|
343
|
+
|
|
344
|
+
Runs the latest sprint phase-by-phase. Automatically picks the most recent sprint.
|
|
345
|
+
|
|
346
|
+
The loop works like this:
|
|
347
|
+
|
|
348
|
+
1. complete one phase
|
|
349
|
+
2. mark completed tasks in:
|
|
350
|
+
|
|
351
|
+
```txt
|
|
352
|
+
./sprints/<sprint_number>/TASKS.md
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
3. compact the conversation/context
|
|
356
|
+
4. proceed to the next phase
|
|
357
|
+
5. repeat until the sprint is complete
|
|
358
|
+
|
|
359
|
+
The model signals the end of a phase by calling a special `end_phase` tool.
|
|
360
|
+
|
|
361
|
+
This keeps long-running projects simple, resumable, and grounded in actual files.
|
|
362
|
+
|
|
363
|
+
### Does it work?
|
|
364
|
+
|
|
365
|
+
Watch a drastically sped-up video of `Qwen/Qwen3.6-27B` working unattended for over an hour on this sprint prompt:
|
|
366
|
+
|
|
367
|
+
```text
|
|
368
|
+
create WebOS a fully functional web-based operating system with apps, games and everything
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
https://github.com/user-attachments/assets/92670a55-a3c4-4c31-a4a2-0afc449f0137
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
And judge the result yourself [here](https://qwen36-27b-moonpi-webos.netlify.app/).
|
|
375
|
+
|
|
376
|
+
## Custom Providers
|
|
377
|
+
|
|
378
|
+
moonpi includes the support from some custom providers.
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
### Synthetic Provider
|
|
382
|
+
|
|
383
|
+
Moonpi registers Synthetic as the `synthetic` provider using the OpenAI-compatible endpoint.
|
|
384
|
+
|
|
385
|
+
Configure credentials with either:
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
export SYNTHETIC_API_KEY=...
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
or run:
|
|
392
|
+
|
|
393
|
+
```text
|
|
394
|
+
/login
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Use `/model` to select a `synthetic` model. Use `/synthetic:quotas` to show your weekly token and rolling 5h usage quotas:
|
|
398
|
+
|
|
399
|
+

|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
## Why moonpi?
|
|
403
|
+
|
|
404
|
+
moonpi is not trying to be a giant agent framework.
|
|
405
|
+
|
|
406
|
+
It does not try to invent a new architecture for every task.
|
|
407
|
+
|
|
408
|
+
It does not summon a committee of subagents to discuss whether a file should be edited.
|
|
409
|
+
|
|
410
|
+
It gives the coding agent a simple structure:
|
|
411
|
+
|
|
412
|
+
* plan when needed
|
|
413
|
+
* act when needed
|
|
414
|
+
* keep the plan in context
|
|
415
|
+
* inject the right project files up front
|
|
416
|
+
* track work explicitly
|
|
417
|
+
* stay inside the project
|
|
418
|
+
* read before writing
|
|
419
|
+
* compact after meaningful phases
|
|
420
|
+
* keep project docs alive
|
|
421
|
+
|
|
422
|
+
That is usually enough.
|
|
423
|
+
|
|
424
|
+
And when it is not enough, it is still better than burning tokens on fake organizational charts for imaginary agents.
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
> **Fun Fact:** I used `moonpi` to build `moonpi`, making it a bootstrapped coding agent.
|
|
428
|
+
|
|
429
|
+
## License
|
|
430
|
+
|
|
431
|
+
MIT
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="780" height="260" viewBox="0 0 780 260" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">MoonPi ASCII banner</title>
|
|
3
|
+
<desc id="desc">A monospaced SVG rendering of the MoonPi orbit-note crescent ASCII logo, using a gold terminal-style palette.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<filter id="softShadow" x="-10%" y="-10%" width="120%" height="120%">
|
|
6
|
+
<feDropShadow dx="0" dy="8" stdDeviation="10" flood-color="#000000" flood-opacity="0.35"/>
|
|
7
|
+
</filter>
|
|
8
|
+
</defs>
|
|
9
|
+
<rect width="780" height="260" rx="22" fill="#101014"/>
|
|
10
|
+
<rect x="16" y="16" width="748" height="228" rx="16" fill="#15151b" stroke="#2a2a33" stroke-width="1.5" filter="url(#softShadow)"/>
|
|
11
|
+
|
|
12
|
+
<text x="42" y="58"
|
|
13
|
+
xml:space="preserve"
|
|
14
|
+
font-family="SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace"
|
|
15
|
+
font-size="22"
|
|
16
|
+
font-weight="500"
|
|
17
|
+
letter-spacing="0"
|
|
18
|
+
dominant-baseline="text-before-edge">
|
|
19
|
+
<tspan x="42" y="46" fill="#d7af5f"> _.._</tspan><tspan fill="#444444"> .-.</tspan>
|
|
20
|
+
<tspan x="42" y="76" fill="#ffd787"> .' .-'`</tspan><tspan fill="#444444"> .-' '-.</tspan>
|
|
21
|
+
<tspan x="42" y="106" fill="#ffffaf"> / /</tspan><tspan fill="#15151b"> </tspan><tspan fill="#ffd700" font-weight="800">π</tspan><tspan fill="#15151b"> </tspan><tspan fill="#ffffaf" font-weight="800">moonpi</tspan><tspan fill="#444444"> )</tspan>
|
|
22
|
+
<tspan x="42" y="136" fill="#ffffd7"> | |</tspan><tspan fill="#444444"> '-. .-'</tspan>
|
|
23
|
+
<tspan x="42" y="166" fill="#ffffaf"> \ '.___.;</tspan><tspan fill="#444444"> '-'</tspan><tspan fill="#808080"> coding agent</tspan>
|
|
24
|
+
<tspan x="42" y="196" fill="#ffd787"> '._ _.'</tspan>
|
|
25
|
+
<tspan x="42" y="226" fill="#d7af5f"> ``</tspan>
|
|
26
|
+
</text>
|
|
27
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "moonpi",
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "Plan, Act, Auto, Fast, TODO, context, and sprint workflows for pi.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/galatolofederico/moonpi.git"
|
|
10
|
+
},
|
|
11
|
+
"author": "Federico Galatolo",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"files": [
|
|
14
|
+
"src/",
|
|
15
|
+
"assets/",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"tsconfig.json"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"pi-package",
|
|
22
|
+
"pi-extension",
|
|
23
|
+
"coding-agent"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
27
|
+
"build:test": "tsc -p tsconfig.json --outDir .test-dist --rootDir src",
|
|
28
|
+
"test": "rm -rf .test-dist && npm run build:test && node --test test/*.test.mjs"
|
|
29
|
+
},
|
|
30
|
+
"pi": {
|
|
31
|
+
"extensions": [
|
|
32
|
+
"./src/index.ts"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@mariozechner/pi-ai": "*",
|
|
37
|
+
"@mariozechner/pi-coding-agent": "*",
|
|
38
|
+
"@mariozechner/pi-tui": "*",
|
|
39
|
+
"typebox": "*"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@mariozechner/pi-ai": "^0.70.6",
|
|
43
|
+
"@mariozechner/pi-coding-agent": "^0.70.6",
|
|
44
|
+
"@mariozechner/pi-tui": "^0.70.6",
|
|
45
|
+
"@types/node": "^24.3.0",
|
|
46
|
+
"typebox": "^1.1.24",
|
|
47
|
+
"typescript": "^5.7.3"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=20.6.0"
|
|
51
|
+
}
|
|
52
|
+
}
|