pi-goal-pro 1.1.0 → 1.2.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,90 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.2.0] - 2026-06-11
9
+
10
+ ### Added
11
+ - `.claude/CLAUDE.md` — agent instructions with git workflow and code style guide
12
+ - `.pi/prompts/commit.md` — AI prompt template for conventional commit messages
13
+ - `.pi/prompts/review.md` — AI prompt template for code review with checklist
14
+ - `VERSION` file — single source of truth for version number
15
+ - `.gitattributes` — consistent line endings (LF) and diff settings
16
+ - `.githooks/pre-commit` — Biome check on staged files before each commit
17
+ - `.githooks/commit-msg` — Enforce conventional commit format on each commit
18
+ - `prepare` script — auto-configures git hooks path on `npm install`
19
+ - `typecheck` script — `tsc --noEmit` for TypeScript validation
20
+ - `check:all` script — runs both Biome check and typecheck
21
+ - `lint-staged` config in package.json for pre-commit checks
22
+
23
+ ### Changed
24
+ - **CI workflow**: renamed from `test.yml`, now with `concurrency` group and `cancel-in-progress: true`
25
+ - **CI split into two jobs**: `quality` (lint + typecheck) and `test` (unit tests on matrix)
26
+ - **CI matrix**: expanded to `os: [ubuntu-latest, macos-latest]` × `node: [20, 22]`
27
+ - **release.yml**: added tag-version verification, pre-release npm tag detection, `make_latest: true`
28
+ - `test:all` script now runs `check:all` (lint + format + typecheck) before tests
29
+ - README CI badge fixed to point to `test.yml` instead of non-existent `ci.yml`
30
+ - `.gitignore` expanded: added IDE files, logs, `.tgz`, coverage, `ideal-git-workflow.md`
31
+ - Fixed TypeScript `typeof theme` scoping error in index.ts
32
+
33
+ ## [1.1.1] - 2026-06-11
34
+
35
+ ### Added
36
+
37
+ - Separate `test.yml` (push/PR) and `release.yml` (tag + workflow_dispatch) CI/CD pipelines
38
+ - `CHANGELOG.md` following Keep a Changelog format
39
+ - `README.ru.md` — Russian language documentation
40
+ - `workflow_dispatch` trigger for manual releases
41
+ - `npm publish --provenance` for supply chain security
42
+
43
+ ### Changed
44
+
45
+ - Split monolithic CI/CD into focused workflows (test quality vs. release)
46
+ - README installation order: npm install first, manual copy second
47
+ - Updated `.gitignore` to exclude `dist/` and `.env`
48
+ - Cleaner package.json scripts (`npm test` = only tests, `npm run test:all` = lint + tests)
49
+
50
+ ### Fixed
51
+
52
+ - Biome linter warnings (non-null assertions → type casts)
53
+ - Message renderer cognitive complexity
54
+
55
+ ## [1.1.0] - 2026-06-11
56
+
57
+ ### Added
58
+
59
+ - 48 unit tests covering all pure functions
60
+ - Biome linter + strict TypeScript configuration
61
+ - GitHub Actions CI/CD pipeline
62
+
63
+ ### Changed
64
+
65
+ - Split README into English (`README.md`) and Russian (`README.ru.md`)
66
+ - Simplified message renderer to reduce cognitive complexity
67
+
68
+ ### Fixed
69
+
70
+ - Non-null assertion warnings in `parseTokenBudget` and `parseMaxAutoTurns`
71
+
72
+ ## [1.0.1] - 2026-06-11
73
+
74
+ ### Added
75
+
76
+ - Initial npm publish
77
+
78
+ ## [1.0.0] - 2026-06-11
79
+
80
+ ### Added
81
+
82
+ - `/goal <objective> [--tokens N] [--max-turns N]` command
83
+ - `get_goal` and `update_goal` tools for the agent
84
+ - Auto-continuation loop with no-progress detection
85
+ - Evidence-based completion (evidence/blocker required)
86
+ - Token budget tracking with auto-pause
87
+ - User input suspends auto-continuation
88
+ - Session entry persistence (survives reload, compaction, tree navigation)
89
+ - Footer status bar
90
+ - Bilingual README (English + Russian)
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <p align="center">
3
3
  <img src="https://img.shields.io/badge/pi-extension-8B5CF6?style=flat-square&logo=pi-hole&logoColor=white" alt="pi extension">
4
4
  <img src="https://img.shields.io/npm/v/pi-goal-pro?style=flat-square&color=cb3837" alt="npm">
5
- <img src="https://img.shields.io/github/actions/workflow/status/izzzzzi/pi-goal-pro/ci.yml?style=flat-square&branch=main" alt="CI">
5
+ <img src="https://img.shields.io/github/actions/workflow/status/izzzzzi/pi-goal-pro/test.yml?style=flat-square&branch=main" alt="CI">
6
6
  <img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="MIT">
7
7
  </p>
8
8
 
@@ -22,15 +22,18 @@ Then walk away. The agent keeps going. When it's done, it reports with evidence.
22
22
 
23
23
  ## Installation
24
24
 
25
+ ### Via npm (recommended)
26
+
25
27
  ```bash
26
- mkdir -p ~/.pi/agent/extensions/pi-goal-pro
27
- # Copy the extension file:
28
- cp ./index.ts ~/.pi/agent/extensions/pi-goal-pro/
28
+ pi install npm:pi-goal-pro
29
+ /reload
29
30
  ```
30
31
 
31
- Then reload Pi:
32
+ ### Manual
32
33
 
33
- ```
34
+ ```bash
35
+ mkdir -p ~/.pi/agent/extensions/pi-goal-pro
36
+ cp ./index.ts ~/.pi/agent/extensions/pi-goal-pro/
34
37
  /reload
35
38
  ```
36
39
 
@@ -283,116 +286,3 @@ Inspired by and building upon:
283
286
  ## License
284
287
 
285
288
  MIT
286
-
287
- ---
288
-
289
- # pi-goal-pro 🎯
290
-
291
- > Персистентные автономные цели для [Pi](https://pi.dev) — с детекцией отсутствия прогресса, завершением на основе доказательств, бюджетом токенов и автопродолжением.
292
-
293
- Задай долгоживущую цель — и агент будет работать автономно, пока не закончит, не будет приостановлен или не упрётся в ограничение. Без необходимости повторять промпт каждый turn.
294
-
295
- ```bash
296
- /goal Переписать auth модуль на JWT с нормальной обработкой ошибок
297
- ```
298
-
299
- Можно отойти от клавиатуры. Агент продолжает сам. Когда закончит — отчитается с доказательствами.
300
-
301
- ---
302
-
303
- ## Установка
304
-
305
- ```bash
306
- mkdir -p ~/.pi/agent/extensions/pi-goal-pro
307
- # Скопировать файл расширения:
308
- cp ./index.ts ~/.pi/agent/extensions/pi-goal-pro/
309
- ```
310
-
311
- Перезагрузить Pi:
312
-
313
- ```
314
- /reload
315
- ```
316
-
317
- Проверить что загрузилось:
318
-
319
- ```
320
- /goal status
321
- ```
322
-
323
- ---
324
-
325
- ## Быстрый старт
326
-
327
- Задай цель — агент начнёт работать:
328
-
329
- ```text
330
- /goal Добавить retry логику в API клиент с экспоненциальной задержкой
331
- ```
332
-
333
- Агент начинает немедленно. Статус в футере:
334
-
335
- ```
336
- 🎯 goal active (1.2K/50K) ← статус в футере
337
- ```
338
-
339
- Управление жизненным циклом:
340
-
341
- ```text
342
- /goal status # Показать текущее состояние
343
- /goal pause # Приостановить активную цель
344
- /goal resume # Возобновить приостановленную
345
- /goal clear # Удалить все цели
346
- ```
347
-
348
- ---
349
-
350
- ## Инструменты агента
351
-
352
- Когда цель активна, агент получает два инструмента:
353
-
354
- **`get_goal`** — прочитать состояние цели.
355
-
356
- **`update_goal`** — завершить цель (с доказательствами) или признать недостижимой (с причиной):
357
-
358
- ```typescript
359
- // Завершено — нужно подтверждение
360
- update_goal({
361
- status: "complete",
362
- evidence: "JWT middleware реализован, 12 тестов проходят, CI без регрессий"
363
- })
364
-
365
- // Недостижимо — нужно объяснение
366
- update_goal({
367
- status: "unmet",
368
- blocker: "Заблокировано решением по JWT библиотеке — ожидание security review"
369
- })
370
- ```
371
-
372
- ---
373
-
374
- ## Как это работает
375
-
376
- Состояние цели хранится в session entry (custom type `pi-goal-pro`). Оно переживает:
377
- - Перезагрузку сессии (`/reload`)
378
- - Компактизацию (compaction)
379
- - Навигацию по дереву сессии (`/tree`)
380
- - Возобновление сессии
381
-
382
- Состояние привязано к ветке — при переходе на другую ветку восстанавливается состояние целей для этой ветки.
383
-
384
- ---
385
-
386
- ## Философия дизайна
387
-
388
- 1. **Пользователь владеет целью** — Агент не может молча изменить objective.
389
- 2. **Доказательства перед завершением** — Агент должен верифицировать по реальным артефактам.
390
- 3. **Никаких бесконечных циклов** — Детекция отсутствия прогресса, лимит turn-ов и бюджет токенов.
391
- 4. **Ввод пользователя приостанавливает** — Когда ты печатаешь, автопродолжение ставится на паузу.
392
- 5. **Состояние привязано к ветке** — `/tree` в другую точку восстанавливает цели этой точки.
393
-
394
- ---
395
-
396
- ## Лицензия
397
-
398
- MIT
package/README.ru.md ADDED
@@ -0,0 +1,252 @@
1
+
2
+ <p align="center">
3
+ <img src="https://img.shields.io/badge/pi-extension-8B5CF6?style=flat-square&logo=pi-hole&logoColor=white" alt="pi extension">
4
+ <img src="https://img.shields.io/npm/v/pi-goal-pro?style=flat-square&color=cb3837" alt="npm">
5
+ <img src="https://img.shields.io/github/actions/workflow/status/izzzzzi/pi-goal-pro/ci.yml?style=flat-square&branch=main" alt="CI">
6
+ <img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="MIT">
7
+ </p>
8
+
9
+ # pi-goal-pro 🎯
10
+
11
+ > Персистентные автономные цели для [Pi](https://pi.dev) — с детекцией отсутствия прогресса, завершением на основе доказательств, бюджетом токенов и автопродолжением.
12
+
13
+ Задай долгоживущую цель — и агент будет работать автономно, пока не закончит, не будет приостановлен или не упрётся в ограничение. Без необходимости повторять промпт каждый turn.
14
+
15
+ ```bash
16
+ /goal Переписать auth модуль на JWT с нормальной обработкой ошибок
17
+ ```
18
+
19
+ Можно отойти от клавиатуры. Агент продолжает сам. Когда закончит — отчитается с доказательствами.
20
+
21
+ ---
22
+
23
+ ## Установка
24
+
25
+ ```bash
26
+ pi install npm:pi-goal-pro
27
+ ```
28
+
29
+ Или вручную:
30
+
31
+ ```bash
32
+ mkdir -p ~/.pi/agent/extensions/pi-goal-pro
33
+ cp ./index.ts ~/.pi/agent/extensions/pi-goal-pro/
34
+ ```
35
+
36
+ Перезагрузить Pi:
37
+
38
+ ```
39
+ /reload
40
+ ```
41
+
42
+ Проверить что загрузилось:
43
+
44
+ ```
45
+ /goal status
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Быстрый старт
51
+
52
+ Задай цель — агент начнёт работать:
53
+
54
+ ```text
55
+ /goal Добавить retry логику в API клиент с экспоненциальной задержкой
56
+ ```
57
+
58
+ Агент начинает немедленно. Статус в футере:
59
+
60
+ ```
61
+ 🎯 goal active (1.2K/50K) ← статус в футере
62
+ ```
63
+
64
+ Управление жизненным циклом:
65
+
66
+ ```text
67
+ /goal status # Показать текущее состояние
68
+ /goal pause # Приостановить активную цель
69
+ /goal resume # Возобновить приостановленную
70
+ /goal clear # Удалить все цели
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Возможности
76
+
77
+ ### 🎯 Установка цели
78
+
79
+ ```text
80
+ /goal Переписать auth модуль
81
+
82
+ # С бюджетом токенов (автопауза при превышении):
83
+ /goal Переписать auth модуль --tokens 100k
84
+
85
+ # С лимитом авто-продолжений:
86
+ /goal Переписать auth модуль --max-turns 10
87
+ ```
88
+
89
+ ### 🤖 Инструменты агента
90
+
91
+ Когда цель активна, агент получает два инструмента:
92
+
93
+ **`get_goal`** — прочитать состояние цели:
94
+
95
+ ```json
96
+ {
97
+ "active": {
98
+ "objective": "Переписать auth модуль на JWT",
99
+ "status": "active",
100
+ "tokens_used": 12400,
101
+ "token_budget": 50000,
102
+ "remaining_tokens": 37600,
103
+ "time_used_seconds": 89,
104
+ "auto_turns": 3,
105
+ "max_auto_turns": 25
106
+ }
107
+ }
108
+ ```
109
+
110
+ **`update_goal`** — завершить цель или признать недостижимой:
111
+
112
+ ```typescript
113
+ // Завершено — нужно подтверждение
114
+ update_goal({
115
+ status: "complete",
116
+ evidence: "JWT middleware реализован, 12 тестов проходят, CI без регрессий"
117
+ })
118
+
119
+ // Недостижимо — нужно объяснение
120
+ update_goal({
121
+ status: "unmet",
122
+ blocker: "Заблокировано решением по JWT библиотеке — ожидание security review"
123
+ })
124
+ ```
125
+
126
+ ### 🔄 Автопродолжение
127
+
128
+ После каждого turn агента расширение автоматически отправляет continuation prompt, если:
129
+ - Цель всё ещё `active`
130
+ - Предыдущий turn был goal-driven
131
+ - Пользователь ничего не вводил (ввод приостанавливает автопродолжение)
132
+ - Не достигнуты лимиты
133
+
134
+ ### 🛡️ Детекция отсутствия прогресса
135
+
136
+ Если агент генерирует очень мало выходных токенов (по умолчанию <50) 2 раза подряд, цель автоматически приостанавливается:
137
+
138
+ ```
139
+ ⏸ Goal paused (no progress for 2 turns). Use /goal resume to continue.
140
+ ```
141
+
142
+ Это предотвращает бесконечные циклы, когда агент просто подтверждает получение без реального прогресса.
143
+
144
+ ### 💰 Бюджет токенов
145
+
146
+ Установи бюджет с `--tokens`:
147
+
148
+ ```text
149
+ /goal Написать документацию для всех API эндпоинтов --tokens 100k
150
+ ```
151
+
152
+ Когда бюджет исчерпан, цель приостанавливается с wrap-up промптом — агент подводит итог.
153
+
154
+ ### 📋 Завершение с доказательствами
155
+
156
+ Агент обязан предоставить конкретные доказательства перед отметкой цели как выполненной. Это предотвращает преждевременные "done" и гарантирует верификацию по реальным файлам, тестам и выводам команд.
157
+
158
+ ---
159
+
160
+ ## Команды
161
+
162
+ | Команда | Описание |
163
+ |---------|----------|
164
+ | `/goal <objective>` | Установить новую цель |
165
+ | `/goal <text> --tokens N` | Цель с бюджетом токенов |
166
+ | `/goal <text> --max-turns N` | Цель с лимитом авто-продолжений |
167
+ | `/goal status` | Показать состояние |
168
+ | `/goal pause` | Приостановить |
169
+ | `/goal resume` | Возобновить |
170
+ | `/goal clear` | Удалить все |
171
+ | `/goal help` | Справка |
172
+
173
+ ---
174
+
175
+ ## Как это работает
176
+
177
+ ```
178
+ /goal Переписать auth модуль
179
+
180
+
181
+ ✓ Цель создана, сохранена в session entry
182
+ ✓ Агент получил get_goal + update_goal
183
+ ✓ Первое продолжение запущено немедленно
184
+
185
+
186
+ ┌── Цикл автопродолжения ───────────────────┐
187
+ │ │
188
+ │ turn_start → turn_end → agent_end │
189
+ │ │ │
190
+ │ ┌─────────┴─────────┐ │
191
+ │ │ Цель активна? │ │
192
+ │ │ Нет прогресса? │ │
193
+ │ │ Пользователь ввёл?│ │
194
+ │ │ Бюджет исчерпан? │ │
195
+ │ │ Лимит turn-ов? │ │
196
+ │ └─────────┬─────────┘ │
197
+ │ │ │
198
+ │ ┌─────────┴──────────┐ │
199
+ │ │ Да → continuation │ │
200
+ │ │ Нет → stop/pause │ │
201
+ │ └────────────────────┘ │
202
+ │ │
203
+ └───────────────────────────────────────────┘
204
+
205
+
206
+ Агент вызывает update_goal({ status: "complete", evidence })
207
+ → Цель архивирована, агент остановлен
208
+ ```
209
+
210
+ ### Сохранение состояния
211
+
212
+ Состояние цели хранится в session entry (custom type `pi-goal-pro`). Оно переживает:
213
+ - Перезагрузку сессии (`/reload`)
214
+ - Компактизацию (compaction)
215
+ - Навигацию по дереву сессии (`/tree`)
216
+ - Возобновление сессии
217
+
218
+ Состояние привязано к ветке — при переходе на другую ветку восстанавливается состояние целей для этой ветки.
219
+
220
+ ---
221
+
222
+ ## Философия дизайна
223
+
224
+ 1. **Пользователь владеет целью** — Агент не может молча изменить objective.
225
+ 2. **Доказательства перед завершением** — Агент должен верифицировать по реальным артефактам.
226
+ 3. **Никаких бесконечных циклов** — Детекция отсутствия прогресса, лимит turn-ов и бюджет токенов.
227
+ 4. **Ввод пользователя приостанавливает** — Когда ты печатаешь, автопродолжение ставится на паузу.
228
+ 5. **Состояние привязано к ветке** — `/tree` в другую точку восстанавливает цели этой точки.
229
+
230
+ ---
231
+
232
+ ## Разработка
233
+
234
+ Расширение в одном файле — не требует сборки. Правишь `index.ts`, затем `/reload`.
235
+
236
+ Запуск без установки:
237
+
238
+ ```bash
239
+ pi -e ~/.pi/agent/extensions/pi-goal-pro/index.ts
240
+ ```
241
+
242
+ Тесты:
243
+
244
+ ```bash
245
+ node --test tests/
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Лицензия
251
+
252
+ MIT
package/index.ts CHANGED
@@ -691,27 +691,27 @@ Do not call update_goal unless the goal is actually complete.`;
691
691
 
692
692
  // ── Message renderer for goal events ───────────────────────────────
693
693
 
694
- const GOAL_KIND_LABELS: Record<string, (th: typeof theme) => string> = {
695
- active: (th) => th.fg('accent', 'active'),
696
- continuation: (th) => th.fg('muted', 'continuing'),
697
- paused: (th) => th.fg('warning', 'paused'),
698
- resumed: (th) => th.fg('accent', 'resumed'),
699
- cleared: (th) => th.fg('dim', 'cleared'),
700
- budget_limited: (th) => th.fg('warning', 'budget'),
701
- complete: (th) => th.fg('success', 'achieved'),
702
- unmet: (th) => th.fg('error', 'unmet'),
703
- };
704
-
705
694
  pi.registerMessageRenderer(`${GOAL_STORAGE_TYPE}:event`, (message, options, theme) => {
706
695
  const details = message.details as GoalEvent | undefined;
707
696
  const kind = details?.kind ?? 'continuation';
708
697
  const state = details?.goal ?? null;
709
698
 
699
+ const goalKindLabels: Record<string, (th: typeof theme) => string> = {
700
+ active: (th) => th.fg('accent', 'active'),
701
+ continuation: (th) => th.fg('muted', 'continuing'),
702
+ paused: (th) => th.fg('warning', 'paused'),
703
+ resumed: (th) => th.fg('accent', 'resumed'),
704
+ cleared: (th) => th.fg('dim', 'cleared'),
705
+ budget_limited: (th) => th.fg('warning', 'budget'),
706
+ complete: (th) => th.fg('success', 'achieved'),
707
+ unmet: (th) => th.fg('error', 'unmet'),
708
+ };
709
+
710
710
  const renderGoalEvent = (_width: number): string[] => {
711
711
  const lines: string[] = [];
712
712
  const isExpanded = options.expanded;
713
713
  const prefix = theme.fg('accent', theme.bold('Goal'));
714
- const kindLabel = (GOAL_KIND_LABELS[kind] ?? ((th: typeof theme) => th.fg('text', kind)))(theme);
714
+ const kindLabel = (goalKindLabels[kind] ?? ((th: typeof theme) => th.fg('text', kind)))(theme);
715
715
  const statusText = theme.fg('dim', isExpanded ? '' : '(ctrl+o to expand)');
716
716
 
717
717
  lines.push(`${prefix} ${kindLabel} ${!isExpanded ? statusText : ''}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-pro",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Persistent autonomous goals for Pi — with no-progress detection, evidence-based completion, token budgets, and auto-continuation",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -8,6 +8,8 @@
8
8
  "files": [
9
9
  "index.ts",
10
10
  "README.md",
11
+ "README.ru.md",
12
+ "CHANGELOG.md",
11
13
  "LICENSE"
12
14
  ],
13
15
  "keywords": [
@@ -53,11 +55,19 @@
53
55
  "tsx": "^4.0.0"
54
56
  },
55
57
  "scripts": {
56
- "test": "npm run check && npm run test:unit",
58
+ "test": "npm run test:unit",
57
59
  "test:unit": "tsx --test tests/index.test.ts",
60
+ "test:all": "npm run check:all && npm run test:unit",
61
+ "lint": "biome lint .",
58
62
  "check": "biome check .",
63
+ "check:all": "npm run check && npm run typecheck",
64
+ "typecheck": "tsc --noEmit",
59
65
  "format": "biome format --write .",
60
- "lint": "biome lint .",
66
+ "prepare": "git config core.hooksPath .githooks",
61
67
  "dev": "pi -e ./index.ts"
68
+ },
69
+ "lint-staged": {
70
+ "*.{ts,tsx}": ["npx @biomejs/biome check --write", "npx tsc --noEmit --pretty"],
71
+ "*.{json,md,yaml}": ["npx @biomejs/biome format --write"]
62
72
  }
63
73
  }