@maxiaochao/pi-toolkit 0.9.1 → 0.9.3

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 CHANGED
@@ -1,3 +1,11 @@
1
+ ## 2026-09-30 - v0.9.3
2
+
3
+ - refine global agent guidance and add repository issue, triage, and domain instructions
4
+
5
+ ## 2026-09-30 - v0.9.2
6
+
7
+ - show contiguous queue positions in the todo widget while retaining stable internal task IDs
8
+
1
9
  ## 2026-09-30 - v0.9.1
2
10
 
3
11
  - redesign the todo lifecycle with plan replacement, cancellation, automatic advancement, active-only widget rendering, concise model guidance, and deterministic state tests
package/README.md CHANGED
@@ -38,7 +38,7 @@ To synchronize the file directly from a checkout instead:
38
38
  bash scripts/install.sh
39
39
  ```
40
40
 
41
- The `todo` tool maintains a session checklist for explicit plans and multi-step work. It automatically keeps one task active and advances the next queued task; `replace` starts a clean plan after a change of direction, while `cancelled` records obsolete work honestly. The persistent widget shows active work only, and `/todos` shows active and closed tasks in the current plan.
41
+ The `todo` tool maintains a session checklist for explicit plans and multi-step work. It automatically keeps one task active and advances the next queued task; `replace` starts a clean plan after a change of direction, while `cancelled` records obsolete work honestly. The persistent widget numbers active work by queue position; `/todos` shows active and closed tasks with their stable internal IDs.
42
42
 
43
43
  The `/btw` side chat is a separate agent session. It can inspect the main conversation and repository, and its thread stays out of the main context until you close it and choose to inject a summary. Use `/btw` to open it or `/btw <question>` to ask directly. While the BTW overlay has focus, use `Up` / `Down` to scroll its transcript one line at a time and `PageUp` / `PageDown` to move by one transcript page.
44
44
 
@@ -1,5 +1,6 @@
1
1
  import assert from "node:assert/strict";
2
2
  import {
3
+ activeTodoRows,
3
4
  activeTodos,
4
5
  applyTodoAction,
5
6
  restoreTodoState,
@@ -7,6 +8,19 @@ import {
7
8
 
8
9
  const empty = { todos: [], nextId: 1 };
9
10
 
11
+ assert.deepEqual(
12
+ activeTodoRows([
13
+ { id: 8, text: "closed", status: "done" },
14
+ { id: 9, text: "current", status: "doing" },
15
+ { id: 11, text: "next", status: "todo" },
16
+ ]).map(({ position, todo }) => ({ position, id: todo.id })),
17
+ [
18
+ { position: 1, id: 9 },
19
+ { position: 2, id: 11 },
20
+ ],
21
+ "active rows expose contiguous queue positions independently of internal IDs",
22
+ );
23
+
10
24
  const replaced = applyTodoAction(empty, {
11
25
  action: "replace",
12
26
  items: ["Inspect the failure", "Implement the fix", "Run verification"],
@@ -19,6 +19,11 @@ export interface TodoState {
19
19
  nextId: number;
20
20
  }
21
21
 
22
+ export interface ActiveTodoRow {
23
+ position: number;
24
+ todo: Todo;
25
+ }
26
+
22
27
  export interface TodoActionInput {
23
28
  action: TodoAction;
24
29
  text?: string;
@@ -73,6 +78,10 @@ export function activeTodos(todos: Todo[]): Todo[] {
73
78
  return todos.filter((todo) => todo.status === "doing" || todo.status === "todo");
74
79
  }
75
80
 
81
+ export function activeTodoRows(todos: Todo[]): ActiveTodoRow[] {
82
+ return activeTodos(todos).map((todo, index) => ({ position: index + 1, todo }));
83
+ }
84
+
76
85
  function cloneState(state: TodoState): TodoState {
77
86
  return { todos: state.todos.map((todo) => ({ ...todo })), nextId: state.nextId };
78
87
  }
@@ -9,7 +9,7 @@ import type { ExtensionAPI, ExtensionContext, Theme } from "@earendil-works/pi-c
9
9
  import { matchesKey, Text, truncateToWidth } from "@earendil-works/pi-tui";
10
10
  import { Type } from "typebox";
11
11
  import {
12
- activeTodos,
12
+ activeTodoRows,
13
13
  applyTodoAction,
14
14
  countTodoStatuses,
15
15
  normalizeTodo,
@@ -80,6 +80,11 @@ function renderTodoLine(theme: Theme, todo: Todo): string {
80
80
  return `${icon} ${theme.fg("accent", `#${todo.id}`)} ${theme.fg("text", todo.text)}`;
81
81
  }
82
82
 
83
+ function renderActiveTodoLine(theme: Theme, todo: Todo, position: number): string {
84
+ const icon = themedStatus(theme, todo.status, statusMarker(todo.status));
85
+ return `${icon} ${theme.fg("accent", `${position}.`)} ${theme.fg("text", todo.text)}`;
86
+ }
87
+
83
88
  class TodoListComponent {
84
89
  private cachedWidth?: number;
85
90
  private cachedLines?: string[];
@@ -134,7 +139,7 @@ export default function (pi: ExtensionAPI) {
134
139
 
135
140
  const refreshUI = (ctx: ExtensionContext) => {
136
141
  if (!ctx.hasUI) return;
137
- const visible = activeTodos(state.todos);
142
+ const visible = activeTodoRows(state.todos);
138
143
  if (visible.length === 0) {
139
144
  ctx.ui.setWidget(WIDGET_KEY, undefined);
140
145
  return;
@@ -146,7 +151,7 @@ export default function (pi: ExtensionAPI) {
146
151
  render(width: number): string[] {
147
152
  return [
148
153
  truncateToWidth(`${theme.fg("accent", "●")} ${theme.fg("muted", taskSummary(state.todos))}`, width),
149
- ...sortedTodos(visible).map((todo) => truncateToWidth(` ${renderTodoLine(theme, todo)}`, width)),
154
+ ...visible.map(({ position, todo }) => truncateToWidth(` ${renderActiveTodoLine(theme, todo, position)}`, width)),
150
155
  ];
151
156
  },
152
157
  invalidate() {},
package/global/AGENTS.md CHANGED
@@ -1,51 +1,38 @@
1
1
  # AGENTS.md
2
2
 
3
- Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.
4
-
5
- **Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
3
+ Behavioral guidelines to reduce common LLM coding mistakes. Project-specific instructions override this file when they conflict.
6
4
 
7
5
  ## 1. Think Before Coding
8
6
 
9
- **Don't assume. Don't hide confusion. Surface tradeoffs.**
7
+ **Surface tradeoffs. Name confusion instead of resolving it silently.**
10
8
 
11
- Before implementing:
12
- - State your assumptions explicitly. If uncertain, ask.
13
- - If multiple interpretations exist, present them - don't pick silently.
9
+ - State your material assumptions explicitly.
10
+ - If multiple interpretations exist, present them rather than picking one silently.
14
11
  - If a simpler approach exists, say so. Push back when warranted.
15
- - If something is unclear, stop. Name what's confusing. Ask.
16
- - If requirements conflict (e.g., durability vs latency, correctness vs speed), name the conflict explicitly. Never average conflicting requirements into something that satisfies neither.
12
+ - If requirements conflict (durability vs latency, correctness vs speed), name the conflict explicitly. Never average conflicting requirements into something that satisfies neither.
13
+ - When unresolved ambiguity would materially change the result, ask. When no human is reachable (headless, async, subagent), choose the interpretation you can defend, state it as an assumption, and proceed under Rule 4.
17
14
 
18
15
  ## 2. Simplicity First
19
16
 
20
- **Minimum code that solves the problem. Nothing speculative.**
21
-
22
- - No features beyond what was asked.
23
- - No abstractions for single-use code.
24
- - No "flexibility" or "configurability" that wasn't requested.
25
- - No error handling for impossible scenarios.
26
- - If you write 200 lines and it could be 50, rewrite.
17
+ **YAGNI cuts what you don't need; KISS keeps what remains simple.**
27
18
 
28
- Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
19
+ - Build what was asked, for the callers that exist today.
20
+ - Introduce an abstraction after repeated use reveals a stable concept.
21
+ - For states excluded by enforced invariants, fail visibly instead of inventing fallback behavior.
22
+ - Each function you write does one thing. If it runs past a couple of screens or nests past three levels, review whether splitting it improves clarity.
29
23
 
30
24
  ## 3. Surgical Changes
31
25
 
32
26
  **Touch only what you must. Clean up only your own mess.**
33
27
 
34
- When editing existing code:
35
- - Don't "improve" adjacent code, comments, or formatting.
36
- - Don't refactor things that aren't broken.
37
- - Match existing style, even if you'd do it differently.
38
- - If you notice unrelated dead code, mention it - don't delete it.
39
-
40
- When your changes create orphans:
41
- - Remove imports/variables/functions that YOUR changes made unused.
42
- - Don't remove pre-existing dead code unless asked.
28
+ The test: every changed line traces to the user's request, or to a defect that request reveals.
43
29
 
44
- The test: Every changed line should trace directly to the user's request.
30
+ - Match existing style, even if you'd do it differently.
31
+ - Remove imports, variables, and functions that YOUR changes made unused. Leave pre-existing dead code in place and mention it.
45
32
 
46
33
  When fixing a bug, fix the root cause, not the symptom. Find where the defect actually lives:
47
- - Grep every caller of the function you touch; a report names a symptom, and patching only the path the ticket mentions leaves sibling callers still broken.
48
- - If the shared function is wrong, fix it once - do not scatter per-caller guards.
34
+ - Find every statically discoverable caller and relevant implementation; a report names a symptom, and patching only the path the ticket mentions leaves sibling callers still broken.
35
+ - If the shared function is wrong, fix it once - do not scatter per-caller guards. Name the sibling callers the fix now affects.
49
36
  - If one caller is wrong, fix that caller - do not add defensive handling to a correct shared function.
50
37
 
51
38
  ## 4. Goal-Driven Execution
@@ -56,11 +43,10 @@ Transform tasks into verifiable goals:
56
43
  - "Add validation" -> "Write tests for invalid inputs, then make them pass"
57
44
  - "Fix the bug" -> "Write a test that reproduces it, then make it pass"
58
45
  - "Refactor X" -> "Ensure tests pass before and after"
46
+ - "Make X fast" -> "Write and test a simple reference implementation, then optimize against its results"
59
47
 
60
- For multi-step tasks, state a brief plan:
48
+ For multi-step or materially ambiguous tasks, state a brief plan where every step carries its own check:
61
49
  1. [Step] -> verify: [check]
62
- 2. [Step] -> verify: [check]
63
- 3. [Step] -> verify: [check]
64
50
 
65
51
  Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
66
52
 
@@ -68,32 +54,21 @@ Strong success criteria let you loop independently. Weak criteria ("make it work
68
54
 
69
55
  **Understand adjacent code before changing it. "Looks orthogonal" is a dangerous assumption.**
70
56
 
71
- Before adding code to any file:
57
+ Before changing a file:
72
58
  - Read the file's exports and public API.
73
59
  - Read the immediate callers of the function you're modifying.
74
- - Check shared utilities in the same module.
75
- - If you're unsure why code is structured a certain way, ask before writing.
76
60
 
77
61
  ## 6. Fail Visibly, Not Silently
78
62
 
79
- **Silent skips are failures. Surface uncertainty instead of hiding it.**
63
+ **Silent skips are failures.**
80
64
 
81
65
  - "Completed" is wrong if anything was silently skipped.
82
- - "Tests pass" is wrong if any test was skipped.
83
- - Default to surfacing uncertainty. When in doubt, over-communicate what you're unsure about.
66
+ - "Tests pass" is wrong if any required test was skipped or not run.
84
67
  - If a required input, file, or tool is missing (or a step is impossible under the stated constraints), do NOT fabricate it to make a check pass. Report what is missing and what you need.
85
68
 
86
69
  ## 7. Reuse Before Writing
87
70
 
88
71
  **Before writing new code, check in order:**
89
- 1. Does it already exist in this codebase? Reuse it - do not re-implement it yourself, even with the standard library. (If the existing helper is itself the bug, fix it once - see Rule 3.)
90
- 2. Does the standard library cover it? Use it.
91
- 3. Only then: write the minimum code that works.
92
-
93
- ## 8. Use Available Editing Tools
94
-
95
- **Follow the current harness's tool surface; do not assume a shell patch helper exists.**
96
-
97
- - Use the native file-editing tools exposed by the current environment. In pi, use `edit` for precise replacements and `write` for new files or complete rewrites.
98
- - Do not run `apply_patch` as a shell command unless `command -v apply_patch` confirms that executable is available.
99
- - If the harness exposes `apply_patch` as a dedicated tool rather than a command, invoke it only through that tool interface.
72
+ 1. Reuse an existing project abstraction when it encodes project semantics. (If it is itself the bug, fix it once - see Rule 3.)
73
+ 2. Otherwise use the standard library or a direct dependency already declared by the project.
74
+ 3. Only then write it yourself.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maxiaochao/pi-toolkit",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "Personal pi coding agent toolkit: /todos, /btw, /cache_export and apply_patch extensions, browser automation, and bundled theme/skills.",
5
5
  "type": "module",
6
6
  "keywords": [