@oh-my-pi/pi-coding-agent 14.5.8 → 14.5.9
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 +22 -0
- package/package.json +7 -7
- package/src/config/settings-schema.ts +3 -3
- package/src/edit/modes/atom.lark +7 -5
- package/src/edit/modes/atom.ts +462 -56
- package/src/edit/modes/hashline.ts +21 -1
- package/src/lsp/index.ts +2 -4
- package/src/lsp/render.ts +0 -3
- package/src/lsp/types.ts +1 -4
- package/src/lsp/utils.ts +18 -14
- package/src/modes/controllers/command-controller.ts +17 -0
- package/src/modes/controllers/input-controller.ts +7 -1
- package/src/modes/interactive-mode.ts +30 -23
- package/src/modes/types.ts +4 -2
- package/src/modes/utils/context-usage.ts +294 -0
- package/src/prompts/tools/atom.md +99 -44
- package/src/prompts/tools/exit-plan-mode.md +5 -39
- package/src/prompts/tools/lsp.md +2 -3
- package/src/prompts/tools/{run-command.md → recipe.md} +1 -1
- package/src/prompts/tools/task.md +34 -147
- package/src/prompts/tools/todo-write.md +22 -64
- package/src/session/compaction/compaction.ts +35 -22
- package/src/session/session-dump-format.ts +1 -0
- package/src/slash-commands/builtin-registry.ts +12 -5
- package/src/tools/debug.ts +57 -70
- package/src/tools/index.ts +7 -7
- package/src/tools/{run-command → recipe}/index.ts +19 -19
- package/src/tools/recipe/render.ts +19 -0
- package/src/tools/{run-command → recipe}/runner.ts +28 -7
- package/src/tools/{run-command → recipe}/runners/pkg.ts +23 -53
- package/src/tools/renderers.ts +2 -2
- package/src/tools/run-command/render.ts +0 -18
- /package/src/tools/{run-command → recipe}/runners/cargo.ts +0 -0
- /package/src/tools/{run-command → recipe}/runners/index.ts +0 -0
- /package/src/tools/{run-command → recipe}/runners/just.ts +0 -0
- /package/src/tools/{run-command → recipe}/runners/make.ts +0 -0
- /package/src/tools/{run-command → recipe}/runners/task.ts +0 -0
|
@@ -1,26 +1,45 @@
|
|
|
1
|
-
Your patch language is a compact,
|
|
1
|
+
Your patch language is a compact, line-anchored edit format.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
A Lid is
|
|
3
|
+
A patch contains one or more file sections. The first non-blank line of every section **MUST** be `---PATH`.
|
|
4
|
+
A "Lid" is a per-line anchor emitted by `read`, `grep`, etc. — `<lineNumber><2-letter-hash>`, e.g. `5th`, `123ab`. You **MUST** copy a Lid verbatim from the latest output for the file you're editing.
|
|
5
|
+
|
|
6
|
+
This format is purely textual. The tool has NO awareness of language, indentation, brackets, fences, or table widths. You are responsible for emitting valid syntax in your replacements/insertions.
|
|
5
7
|
|
|
6
8
|
<ops>
|
|
7
|
-
---PATH
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
^
|
|
12
|
-
|
|
13
|
-
+
|
|
14
|
-
Lid=
|
|
15
|
-
|
|
9
|
+
---PATH start a section editing PATH; cursor begins at EOF
|
|
10
|
+
^ move cursor to BOF (before line 1)
|
|
11
|
+
$ move cursor to EOF (after the last line)
|
|
12
|
+
@Lid move cursor to AFTER the anchored line (does not modify the file)
|
|
13
|
+
^Lid move cursor to BEFORE the anchored line (does not modify the file)
|
|
14
|
+
+TEXT insert one line containing TEXT at the cursor
|
|
15
|
+
+ insert one blank line at the cursor
|
|
16
|
+
Lid=TEXT replace the anchored line with TEXT
|
|
17
|
+
LidA..LidB=TEXT replace the range with one line; following `\TEXT` lines append literal lines to the replacement
|
|
18
|
+
\TEXT append literal TEXT to the active replacement (after `Lid=…` or `LidA..LidB=…`)
|
|
19
|
+
\ append a blank line to the active replacement
|
|
20
|
+
Lid= blank the anchored line's content but KEEP the line (results in an empty line, NOT a removed line; use `-Lid` to remove)
|
|
21
|
+
-Lid delete the anchored line (repeat for multi-line delete)
|
|
22
|
+
-LidA..LidB delete the contiguous line range LidA..LidB (inclusive)
|
|
23
|
+
!rm delete the section's PATH (**MUST** be the only op in the section)
|
|
24
|
+
!mv DEST rename the section's PATH to DEST (**MUST** be the only op in the section)
|
|
16
25
|
</ops>
|
|
17
26
|
|
|
18
27
|
<rules>
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
- Consecutive `+
|
|
22
|
-
- `Lid=
|
|
23
|
-
-
|
|
28
|
+
- Cursor-only ops (`^`, `$`, `@Lid`, `^Lid`) reposition without modifying. To insert anything you **MUST** follow them with `+TEXT` (or `+` for a blank).
|
|
29
|
+
- TEXT in `+TEXT`, `Lid=TEXT`, and `\TEXT` is literal line content, INCLUDING leading whitespace. You **MUST NOT** trim or re-indent it.
|
|
30
|
+
- Consecutive `+TEXT` ops produce consecutive lines in the order written. You **MUST NOT** separate them with a stray `+` unless you intend to insert a blank line.
|
|
31
|
+
- `Lid=TEXT` rewrites ONE line. To rewrite K adjacent lines, you **MUST** use `LidA..LidB=FIRST_LINE` followed immediately by `\NEXT_LINE` continuation lines (canonical form for any block replacement). You **MUST** use bare `\` for blank replacement lines.
|
|
32
|
+
- You **MUST** prefix every replacement continuation line with `\`, especially when the replacement line starts with edit syntax characters such as `#`, `+`, `-`, `@`, `$`, `^`, `!`, or a Lid-shaped token.
|
|
33
|
+
- `\TEXT` **MUST** appear only immediately after an active `Lid=…` or `LidA..LidB=…` replacement. It **MUST NOT** be used as a general insert operator.
|
|
34
|
+
- A `\TEXT` line **MUST** be the immediate continuation of a `Lid=…` or `LidA..LidB=…` op on the line above (or another `\` line rooted in one). If the line above is `+TEXT`, a bare Lid, a cursor op, or whitespace, the `\` is invalid and the tool will not interpret it as part of a replacement.
|
|
35
|
+
- The legacy `-LidA..LidB` + `+TEXT…` block-rewrite form also works.
|
|
36
|
+
- To insert ABOVE a line, you **MUST** use `^Lid` then `+TEXT`. To insert above line 1, you **MUST** use `^` (BOF) then `+TEXT`. To insert below a line, you **MUST** use `@Lid` then `+TEXT`.
|
|
37
|
+
- Multiple `---PATH` sections **MAY** appear in one input; each section is applied in order.
|
|
38
|
+
- `!rm` / `!mv DEST` **MUST NOT** be combined with line edits in the same section.
|
|
39
|
+
- Lids contain a content hash. If a line has changed since you read it, the tool rejects the edit and shows the current content; you **MUST** re-read and retry with fresh Lids. Small drift (≤5 lines) where the original hash still matches a nearby line auto-rebases with a warning. Larger shifts may show a hash-only candidate, but two-letter hashes collide; verify surrounding content or re-read before using it.
|
|
40
|
+
- After `+TEXT` (or `+`) the cursor advances past the inserted line, so consecutive `+TEXT` ops stack in order. After `Lid=TEXT` the cursor sits on the modified anchor; after `-Lid` it sits on the slot the deleted line vacated. You **MUST** use a fresh `@Lid` / `^Lid` / `^` / `$` to reposition.
|
|
41
|
+
- The tool is syntax-blind: it will not check brackets, indentation, table column counts, or fence integrity. You **MUST** verify indentation-sensitive or structured files after editing (Python, Markdown tables/fences).
|
|
42
|
+
- A section whose PATH does not yet exist creates the file from your `+TEXT` lines (use `^` or `$` then `+TEXT…`). No separate "create file" op is needed.
|
|
24
43
|
</rules>
|
|
25
44
|
|
|
26
45
|
<case file="a.ts">
|
|
@@ -33,11 +52,11 @@ Lid=X replace whole line with X; `Lid=` blanks it out
|
|
|
33
52
|
</case>
|
|
34
53
|
|
|
35
54
|
<examples>
|
|
36
|
-
# Replace line
|
|
55
|
+
# Replace one line (preserve the leading tab from the original)
|
|
37
56
|
---a.ts
|
|
38
57
|
{{hrefr 5}}= return clean.trim().toUpperCase();
|
|
39
58
|
|
|
40
|
-
# Rewrite multiple adjacent lines (delete
|
|
59
|
+
# Rewrite multiple adjacent lines (delete each, then insert new content)
|
|
41
60
|
---a.ts
|
|
42
61
|
-{{hrefr 3}}
|
|
43
62
|
-{{hrefr 4}}
|
|
@@ -47,48 +66,84 @@ Lid=X replace whole line with X; `Lid=` blanks it out
|
|
|
47
66
|
+ return (name || DEF).trim().toUpperCase();
|
|
48
67
|
+}
|
|
49
68
|
|
|
50
|
-
#
|
|
69
|
+
# Same rewrite using a range (equivalent to four `-Lid` lines)
|
|
51
70
|
---a.ts
|
|
52
|
-
|
|
53
|
-
+
|
|
71
|
+
-{{hrefr 3}}..{{hrefr 6}}
|
|
72
|
+
+export function label(name: string): string {
|
|
73
|
+
+ return (name || DEF).trim().toUpperCase();
|
|
74
|
+
+}
|
|
54
75
|
|
|
55
|
-
#
|
|
76
|
+
# Replace a contiguous range with one line (range-replace shorthand)
|
|
56
77
|
---a.ts
|
|
57
|
-
|
|
78
|
+
{{hrefr 3}}..{{hrefr 6}}=export const label = (name: string) => (name || DEF).trim().toUpperCase();
|
|
58
79
|
|
|
59
|
-
#
|
|
80
|
+
# Replace a contiguous range with multiple lines (continuation form)
|
|
60
81
|
---a.ts
|
|
61
|
-
|
|
82
|
+
{{hrefr 3}}..{{hrefr 6}}=export function label(name: string): string {
|
|
83
|
+
\ return (name || DEF).trim().toUpperCase();
|
|
84
|
+
\}
|
|
85
|
+
|
|
86
|
+
# Replace a block with a longer multi-line block, including blank lines (canonical form for refactors)
|
|
87
|
+
---a.ts
|
|
88
|
+
{{hrefr 3}}..{{hrefr 6}}=/** Format a display label, falling back to DEF when empty. */
|
|
89
|
+
\export function label(name: string): string {
|
|
90
|
+
\ const clean = (name || DEF).trim();
|
|
91
|
+
\
|
|
92
|
+
\ if (clean.length === 0) return DEF;
|
|
93
|
+
\ return clean.toUpperCase();
|
|
94
|
+
\}
|
|
95
|
+
|
|
96
|
+
# Insert ABOVE a line
|
|
97
|
+
---a.ts
|
|
98
|
+
^{{hrefr 5}}
|
|
99
|
+
+ const debug = false;
|
|
100
|
+
|
|
101
|
+
# Insert BELOW a line
|
|
102
|
+
---a.ts
|
|
103
|
+
@{{hrefr 4}}
|
|
104
|
+
+ const debug = false;
|
|
105
|
+
|
|
106
|
+
# Insert above the first line (use BOF)
|
|
107
|
+
---a.ts
|
|
108
|
+
^
|
|
62
109
|
+// Copyright (c) 2026
|
|
63
110
|
+
|
|
64
|
-
|
|
111
|
+
|
|
112
|
+
# Append at end of file
|
|
113
|
+
---a.ts
|
|
114
|
+
$
|
|
65
115
|
+export { DEF };
|
|
66
116
|
|
|
67
|
-
#
|
|
117
|
+
# Delete a single line
|
|
68
118
|
---a.ts
|
|
69
|
-
|
|
70
|
-
---b.ts
|
|
71
|
-
!mv a.ts
|
|
119
|
+
-{{hrefr 2}}
|
|
72
120
|
|
|
73
|
-
#
|
|
121
|
+
# Delete the file (no other ops in the section)
|
|
74
122
|
---a.ts
|
|
75
|
-
|
|
123
|
+
!rm
|
|
76
124
|
|
|
77
|
-
#
|
|
125
|
+
# Rename a file
|
|
78
126
|
---a.ts
|
|
79
|
-
|
|
80
|
-
return clean.trim().toUpperCase();
|
|
127
|
+
!mv b.ts
|
|
81
128
|
|
|
82
|
-
#
|
|
129
|
+
# Multi-file edit in one input
|
|
83
130
|
---a.ts
|
|
84
|
-
|
|
85
|
-
|
|
131
|
+
{{hrefr 1}}=const DEF = "user";
|
|
132
|
+
---other.ts
|
|
133
|
+
$
|
|
134
|
+
+// new footer
|
|
86
135
|
</examples>
|
|
87
136
|
|
|
88
137
|
<critical>
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
138
|
+
- You **MUST** copy Lids EXACTLY from the latest read/grep output. You **MUST NOT** guess, shorten, drop letters, or invent line numbers.
|
|
139
|
+
- Current/added preview lines include fresh `LINE+hash|content` anchors. Removed preview lines show deleted content and **MUST NOT** be reused as anchors.
|
|
140
|
+
- You **MUST** emit only lines that change. You **MUST NOT** echo unchanged context; the anchor implies position.
|
|
141
|
+
- You **MUST NOT** write `Lid=<sameTextThatIsAlreadyOnThatLine>`; the tool reports a no-op (no change applied). Emit `Lid=TEXT` only when TEXT differs.
|
|
142
|
+
- A line of the form `Lid|content` (a Lid, then `|`, then text, with NO leading `+`/`-`/`^`/`@`/`\`/`=`/`..`) is **FORBIDDEN**. That shape only appears in `read`/`grep` output as an anchor for *you*; it is never an edit op. If you copy a `Lid|content` line verbatim from a read into a patch, you have made an error — every edit op must start with `+`, `-`, `^`, `@`, `\`, `$`, `!`, or a Lid immediately followed by `=` or `..`.
|
|
143
|
+
- To replace a contiguous block with new content, the canonical form is `LidA..LidB=FIRST_LINE` + `\NEXT_LINE…`. You **MUST NOT** write the old block and then the new block — that is unified-diff thinking and the tool does not understand it. If you find yourself emitting pre-image lines (with or without operators) before your new content, STOP and rewrite the section as a single range-replace.
|
|
144
|
+
- TEXT after `=`, `+`, or `\` includes leading whitespace verbatim. You **MUST NOT** trim or re-indent it.
|
|
145
|
+
- This is NOT unified diff. You **MUST NOT** write `@@` headers, `-OLD`/`+NEW` pairs, context lines, or `+Lid|…` (bad: `+5th|new text`; good: `5th=new text`).
|
|
146
|
+
- You **MUST NOT** split `Lid=TEXT` across two physical lines.
|
|
147
|
+
- For a contiguous range replacement, you **MAY** use either `Lid=FIRST_LINE` + `\NEXT_LINE…` (extends one anchor) or `LidA..LidB=FIRST_LINE` + `\NEXT_LINE…` (collapses an existing range), or fall back to `-LidA..LidB` + `+TEXT…` (delete + insert).
|
|
148
|
+
- The tool is syntax-blind. Indentation, brackets, fences, table widths — you remain responsible.
|
|
94
149
|
</critical>
|
|
@@ -1,40 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
Submits a finalized implementation plan for user approval.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Use
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
- Ready for user review and approval
|
|
8
|
-
</conditions>
|
|
9
|
-
|
|
10
|
-
<instruction>
|
|
11
|
-
- You **MUST** write plan to plan file BEFORE calling this tool
|
|
12
|
-
- Tool reads plan from file—does not take plan content as parameter
|
|
13
|
-
- You **MUST** provide a `title` argument for the final plan artifact (example: `WP_MIGRATION_PLAN`)
|
|
14
|
-
- `.md` is optional in `title`; it is appended automatically when omitted
|
|
15
|
-
- User sees plan contents when reviewing
|
|
16
|
-
</instruction>
|
|
17
|
-
|
|
18
|
-
<output>
|
|
19
|
-
Presents plan to user for approval. If approved, plan mode exits with full tool access restored and the plan is renamed to `local://<title>.md`.
|
|
20
|
-
</output>
|
|
21
|
-
|
|
22
|
-
<examples>
|
|
23
|
-
# Ready
|
|
24
|
-
Plan complete at local://PLAN.md, no open questions.
|
|
25
|
-
→ Call `exit_plan_mode` with `{ "title": "WP_MIGRATION_PLAN" }`
|
|
26
|
-
# Unclear
|
|
27
|
-
Unsure about auth method (OAuth vs JWT).
|
|
28
|
-
→ Use `ask` first to clarify, then call `exit_plan_mode`
|
|
29
|
-
</examples>
|
|
30
|
-
|
|
31
|
-
<avoid>
|
|
32
|
-
- **MUST NOT** call before plan is written to file
|
|
33
|
-
- **MUST NOT** omit `title`
|
|
34
|
-
- **MUST NOT** use `ask` to request plan approval (this tool does that)
|
|
35
|
-
- **MUST NOT** call after pure research tasks (no implementation planned)
|
|
36
|
-
</avoid>
|
|
37
|
-
|
|
38
|
-
<critical>
|
|
39
|
-
You **MUST** only use when planning implementation steps. Research tasks (searching, reading, understanding) do not need this tool.
|
|
40
|
-
</critical>
|
|
3
|
+
Write the plan to `local://PLAN.md` first, then call this with `title` (e.g. `WP_MIGRATION_PLAN`); on approval the file is renamed to `local://<title>.md` and full tool access is restored.
|
|
4
|
+
- Use only after planning implementation steps; not for pure research.
|
|
5
|
+
- **MUST NOT** call before the plan file exists.
|
|
6
|
+
- **MUST NOT** use `ask` to request plan approval — this tool does that.
|
package/src/prompts/tools/lsp.md
CHANGED
|
@@ -17,8 +17,7 @@ Interacts with Language Server Protocol servers for code intelligence.
|
|
|
17
17
|
<parameters>
|
|
18
18
|
- `file`: File path, glob pattern (e.g. `src/**/*.ts`), or `"*"` for workspace scope. Globs are expanded locally before dispatch. `"*"` routes `diagnostics`/`symbols`/`reload` to their workspace-wide form.
|
|
19
19
|
- `line`: 1-indexed line number for position-based actions
|
|
20
|
-
- `symbol`: Substring on the target line used to resolve column automatically
|
|
21
|
-
- `occurrence`: 1-indexed match index when `symbol` appears multiple times on the same line
|
|
20
|
+
- `symbol`: Substring on the target line used to resolve column automatically. Append `#N` to pick the Nth occurrence on that line (1-indexed; default 1) — e.g. `foo#2` selects the second `foo`.
|
|
22
21
|
- `query`: Symbol search query, code-action kind filter (list mode), or code-action selector (apply mode)
|
|
23
22
|
- `new_name`: Required for rename
|
|
24
23
|
- `apply`: Apply edits for rename/code_actions (default true for rename, list mode for code_actions unless explicitly true)
|
|
@@ -29,7 +28,7 @@ Interacts with Language Server Protocol servers for code intelligence.
|
|
|
29
28
|
- Requires running LSP server for target language
|
|
30
29
|
- Some operations require file to be saved to disk
|
|
31
30
|
- Glob expansion samples up to 20 files per request; use `file: "*"` for broader coverage
|
|
32
|
-
- When `symbol` is provided for position-based actions, missing symbols or out-of-bounds `occurrence
|
|
31
|
+
- When `symbol` is provided for position-based actions, missing symbols or out-of-bounds `#N` occurrence selectors return an explicit error instead of silently falling back
|
|
33
32
|
</caution>
|
|
34
33
|
|
|
35
34
|
<critical>
|
|
@@ -10,7 +10,7 @@ Run a recipe / script / target from the project's task runners.
|
|
|
10
10
|
{{#each runners}}
|
|
11
11
|
<runner id="{{id}}" label="{{label}}" command="{{commandPrefix}}">
|
|
12
12
|
{{#each tasks}}
|
|
13
|
-
- `{{name}}{{#if paramSig}} {{paramSig}}{{/if}}`{{#if doc}} — {{doc}}{{/if}}{{#if command}} (`{{command}}`){{/if}}
|
|
13
|
+
- `{{name}}{{#if paramSig}} {{paramSig}}{{/if}}`{{#if doc}} — {{doc}}{{/if}}{{#if command}} (`{{command}}`{{#if cwd}} in `{{cwd}}`{{/if}}){{/if}}
|
|
14
14
|
{{/each}}
|
|
15
15
|
</runner>
|
|
16
16
|
{{/each}}
|
|
@@ -1,167 +1,54 @@
|
|
|
1
1
|
Launches subagents to parallelize workflows.
|
|
2
2
|
|
|
3
3
|
{{#if asyncEnabled}}
|
|
4
|
-
-
|
|
5
|
-
- Use
|
|
4
|
+
- `read jobs://` for state, `read jobs://<id>` for detail.
|
|
5
|
+
- Use `job` (with `poll`) to wait. **MUST NOT** poll `read jobs://` in a loop.
|
|
6
6
|
{{/if}}
|
|
7
7
|
|
|
8
|
-
{{#if
|
|
9
|
-
Current input mode: `default`. Shared `context` and custom task-call `schema` are available.
|
|
10
|
-
{{/if}}
|
|
11
|
-
{{#if schemaFreeMode}}
|
|
12
|
-
Current input mode: `schema-free`. Shared `context` is available; custom task-call `schema` is disabled. For structured output, rely on the agent definition or inherited session schema.
|
|
13
|
-
{{/if}}
|
|
14
|
-
{{#if independentMode}}
|
|
15
|
-
Current input mode: `independent`. Shared `context` and custom `schema` are both disabled. Every assignment must stand on its own.
|
|
16
|
-
{{/if}}
|
|
17
|
-
|
|
18
|
-
{{#if contextEnabled}}
|
|
19
|
-
Subagents lack your conversation history. Every decision, file content, and user requirement they need **MUST** be explicit in `context` or `assignment`.
|
|
20
|
-
{{else}}
|
|
21
|
-
Subagents lack your conversation history. Every decision, file content, and user requirement they need **MUST** be explicit in each task `assignment`.
|
|
22
|
-
{{/if}}
|
|
8
|
+
Subagents have no access to your conversation history. Every fact, file path, and decision they need **MUST** be explicit in {{#if contextEnabled}}`context` or `assignment`{{else}}each `assignment`{{/if}}.
|
|
23
9
|
|
|
24
10
|
<parameters>
|
|
25
|
-
- `agent`:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- `context`:
|
|
31
|
-
{{/if}}
|
|
32
|
-
{{#if
|
|
33
|
-
- `schema`: JSON-encoded JTD schema for expected output. Format lives here — **MUST NOT** be duplicated in assignments.
|
|
34
|
-
{{/if}}
|
|
35
|
-
- `tasks`: Tasks to execute in parallel.
|
|
36
|
-
{{#if isolationEnabled}}
|
|
37
|
-
- `isolated`: Run in isolated environment; returns patches. Use when tasks edit overlapping files.
|
|
38
|
-
{{/if}}
|
|
11
|
+
- `agent`: agent type for all tasks
|
|
12
|
+
- `tasks`: tasks to execute in parallel
|
|
13
|
+
- `.id`: CamelCase, ≤32 chars
|
|
14
|
+
- `.description`: UI label only — subagent never sees it
|
|
15
|
+
- `.assignment`: complete self-contained instructions; one-liners and missing acceptance criteria are PROHIBITED
|
|
16
|
+
{{#if contextEnabled}}- `context`: shared background prepended to every assignment; session-specific only{{/if}}
|
|
17
|
+
{{#if customSchemaEnabled}}- `schema`: JTD schema for expected structured output (do not put format rules in assignments){{/if}}
|
|
18
|
+
{{#if isolationEnabled}}- `isolated`: run in isolated env; use when tasks edit overlapping files{{/if}}
|
|
39
19
|
</parameters>
|
|
40
20
|
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- For large payloads (traces, JSON blobs), write to `local://<path>` and pass the path in {{#if contextEnabled}}`context`{{else}}the relevant `assignment`{{/if}}.
|
|
49
|
-
- Prefer `task` agents that investigate **and** edit in one pass. Launch a dedicated read-only discovery step only when affected files are genuinely unknown.
|
|
50
|
-
</critical>
|
|
51
|
-
|
|
52
|
-
<scope>
|
|
53
|
-
Each task: **at most 3–5 files**. Globs, "update all", or package-wide scope = too broad. Enumerate files explicitly and fan out to a cluster of agents.
|
|
54
|
-
</scope>
|
|
21
|
+
<rules>
|
|
22
|
+
- **MUST NOT** assign tasks to run project-wide build/test/lint. Caller verifies after the batch.
|
|
23
|
+
- Each task: ≤3–5 explicit files. No globs, no "update all", no package-wide scope. Fan out to a cluster instead.
|
|
24
|
+
- Pass large payloads via `local://<path>` URIs, not inline.
|
|
25
|
+
{{#if contextEnabled}}- Put shared constraints in `context` once; do not duplicate across assignments.{{/if}}
|
|
26
|
+
- Prefer agents that investigate **and** edit in one pass; only spin a read-only discovery step when affected files are genuinely unknown.
|
|
27
|
+
</rules>
|
|
55
28
|
|
|
56
29
|
<parallelization>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|---|---|---|
|
|
61
|
-
|Types/interfaces|Consumers|Need contract|
|
|
62
|
-
|API exports|Callers|Need signatures|
|
|
63
|
-
|Core module|Dependents|Import dependency|
|
|
64
|
-
|Schema/migration|App logic|Schema dependency|
|
|
65
|
-
|
|
66
|
-
**Safe to parallelize:** independent modules, isolated file-scoped refactors, tests for existing code.
|
|
30
|
+
Test: can task B run correctly without seeing A's output? If no, sequence A → B.
|
|
31
|
+
Sequential when one task produces a contract (types, API, schema, core module) the other consumes.
|
|
32
|
+
Parallel when tasks touch disjoint files or are independent refactors/tests.
|
|
67
33
|
</parallelization>
|
|
68
34
|
|
|
69
|
-
<templates>
|
|
70
|
-
{{#if contextEnabled}}
|
|
71
|
-
**context:**
|
|
72
|
-
```
|
|
73
|
-
## Goal ← one sentence: what the batch accomplishes
|
|
74
|
-
## Non-goals ← what tasks must not touch
|
|
75
|
-
## Constraints ← MUST/MUST NOT rules and session decisions
|
|
76
|
-
## API Contract ← exact types/signatures if tasks share an interface (omit if N/A)
|
|
77
|
-
## Acceptance ← definition of done; build/lint runs AFTER all tasks complete
|
|
78
|
-
```
|
|
79
|
-
{{else}}
|
|
80
|
-
No shared `context` field exists in this mode. Fold goal, non-goals, constraints, and acceptance criteria into each `assignment`.
|
|
81
|
-
{{/if}}
|
|
82
|
-
**assignment:**
|
|
83
|
-
```
|
|
84
|
-
## Target ← exact file paths; named symbols; explicit non-goals
|
|
85
|
-
## Change ← step-by-step what to add/remove/rename; patterns/APIs to use
|
|
86
|
-
## Edge Cases ← tricky inputs; existing behavior that must survive
|
|
87
|
-
## Acceptance ← observable result proving the task is done; no project-wide commands
|
|
88
|
-
```
|
|
89
|
-
</templates>
|
|
90
|
-
|
|
91
|
-
<checklist>
|
|
92
|
-
Before invoking:
|
|
93
35
|
{{#if contextEnabled}}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
36
|
+
<context-fmt>
|
|
37
|
+
# Goal ← one sentence: what the batch accomplishes
|
|
38
|
+
# Constraints ← **MUST**/**MUST NOT** rules and session decisions
|
|
39
|
+
# Contract ← exact types/signatures if tasks share an interface
|
|
40
|
+
</context-fmt>
|
|
97
41
|
{{/if}}
|
|
98
|
-
- Every `assignment` follows the template; no one-liners; edge cases covered
|
|
99
|
-
- Tasks are truly parallel — you can articulate why none depends on another's output
|
|
100
|
-
- File paths are explicit; no globs
|
|
101
|
-
{{#if customSchemaEnabled}}
|
|
102
|
-
- `schema` is set if you expect structured output
|
|
103
|
-
{{else}}
|
|
104
|
-
- Do not pass a custom task-call `schema` in this mode
|
|
105
|
-
{{/if}}
|
|
106
|
-
</checklist>
|
|
107
|
-
|
|
108
|
-
{{#if contextEnabled}}
|
|
109
|
-
<example label="Rename exported symbol + update all call sites">
|
|
110
|
-
Two tasks with non-overlapping file sets — demonstrates scope partitioning.
|
|
111
42
|
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
## Acceptance (global)
|
|
118
|
-
Caller runs `bun check:ts` after both tasks complete. Tasks must NOT run it.
|
|
119
|
-
</context>
|
|
120
|
-
<tasks>
|
|
121
|
-
<task name="RenameExport">
|
|
122
|
-
<assignment>
|
|
123
|
-
## Target
|
|
124
|
-
- `src/config/parser.ts`: function `parseConfig`
|
|
125
|
-
- If `src/config/index.ts` re-exports it, update the re-export
|
|
126
|
-
- Non-goals: do not touch callers or tests
|
|
127
|
-
|
|
128
|
-
## Change
|
|
129
|
-
- Rename `parseConfig` → `loadConfig` (declaration + any JSDoc references)
|
|
130
|
-
|
|
131
|
-
## Edge Cases
|
|
132
|
-
- Rename all overload signatures if overloaded
|
|
133
|
-
- Internal helpers like `_parseConfigValue` are different symbols — leave untouched
|
|
134
|
-
- Do not add a backwards-compat alias
|
|
135
|
-
|
|
136
|
-
## Acceptance
|
|
137
|
-
- `parseConfig` no longer appears as a top-level export in `parser.ts`
|
|
138
|
-
</assignment>
|
|
139
|
-
</task>
|
|
140
|
-
<task name="UpdateCallers">
|
|
141
|
-
<assignment>
|
|
142
|
-
## Target
|
|
143
|
-
- `src/cli/init.ts`, `src/server/bootstrap.ts`, `src/worker/index.ts`
|
|
144
|
-
- Non-goals: do not touch `src/config/parser.ts` or `src/config/index.ts`
|
|
145
|
-
|
|
146
|
-
## Change
|
|
147
|
-
- Replace `import { parseConfig }` → `import { loadConfig }`
|
|
148
|
-
- Replace every call site `parseConfig(` → `loadConfig(`
|
|
149
|
-
- For `import * as cfg` users, update `cfg.parseConfig` property access
|
|
150
|
-
|
|
151
|
-
## Edge Cases
|
|
152
|
-
- String literals containing "parseConfig" (logs, comments) are documentation — leave them
|
|
153
|
-
- If a file re-exports to an external package boundary, keep the old name via `export { loadConfig as parseConfig }` with a `// TODO: remove after next major` comment
|
|
154
|
-
|
|
155
|
-
## Acceptance
|
|
156
|
-
- No bare `parseConfig` identifier remains in the three target files
|
|
157
|
-
</assignment>
|
|
158
|
-
</task>
|
|
159
|
-
</tasks>
|
|
160
|
-
</example>
|
|
161
|
-
{{/if}}
|
|
43
|
+
<assignment-fmt>
|
|
44
|
+
# Target ← exact files and symbols; explicit non-goals
|
|
45
|
+
# Change ← step-by-step add/remove/rename; APIs and patterns
|
|
46
|
+
# Acceptance ← observable result; no project-wide commands
|
|
47
|
+
</assignment-fmt>
|
|
162
48
|
|
|
49
|
+
<agents>
|
|
163
50
|
{{#list agents join="\n"}}
|
|
164
|
-
|
|
165
|
-
**Tools:** {{default (join tools ", ") "All"}}
|
|
51
|
+
# {{name}}
|
|
166
52
|
{{description}}
|
|
167
53
|
{{/list}}
|
|
54
|
+
</agents>
|
|
@@ -1,69 +1,33 @@
|
|
|
1
|
-
Manages a phased task list
|
|
2
|
-
The next pending task is auto-promoted to `in_progress` after
|
|
1
|
+
Manages a phased task list. Pass `ops`: a flat array of operations.
|
|
2
|
+
The next pending task is auto-promoted to `in_progress` after each completion.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
## Shape
|
|
4
|
+
## Operations
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
{
|
|
11
|
-
ops: [
|
|
12
|
-
{ op: "replace", phases: [...] },
|
|
13
|
-
{ op: "start", task: "task-3" },
|
|
14
|
-
{ op: "done", phase: "Implementation" },
|
|
15
|
-
{ op: "rm" },
|
|
16
|
-
{ op: "drop", task: "task-9" },
|
|
17
|
-
{ op: "append", phase: "Implementation", items: [{ id: "task-10", label: "Run tests" }] },
|
|
18
|
-
],
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Operation fields
|
|
23
|
-
|
|
24
|
-
|Field|Type|When to use|
|
|
6
|
+
|`op`|Required fields|Effect|
|
|
25
7
|
|---|---|---|
|
|
26
|
-
|`
|
|
27
|
-
|`task`|
|
|
28
|
-
|`
|
|
29
|
-
|`
|
|
30
|
-
|`
|
|
31
|
-
|`
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- `
|
|
36
|
-
- `
|
|
37
|
-
- `drop`: marks one task, one phase, or all tasks abandoned
|
|
38
|
-
- `append`: appends `items` to `phase`; creates the phase if missing
|
|
39
|
-
- `replace`: replaces the full todo list
|
|
40
|
-
- `note`: append `text` as a new note attached to `task`. Notes are append-only context the user added; they only render to you when the task is `in_progress`. Other tasks display only a `+N` marker. Use this when you want to leave a follow-up reminder for yourself when you reach a later task.
|
|
41
|
-
|
|
42
|
-
If `done`, `rm`, or `drop` omits both `task` and `phase`, it applies to all tasks.
|
|
43
|
-
|
|
44
|
-
## Task Anatomy
|
|
45
|
-
- `label`: Short label (5-10 words). What is being done, not how.
|
|
46
|
-
- `replace` task `content` should stay short and specific.
|
|
47
|
-
|
|
48
|
-
## Phase Anatomy
|
|
49
|
-
- `name`: Short, human-readable noun phrase (1-3 words). Capitalize naturally.
|
|
50
|
-
- Always prefix with a roman-numeral ordinal (`I.`, `II.`, `III.`, `IV.`, …) to convey ordering — e.g. `I. Foundation`, `II. Auth`, `III. Routing`. Single-phase plans use `I.` too.
|
|
51
|
-
- You **MUST NOT** use snake_case, `Phase1_*`, arabic numerals (`1.`), or letter prefixes (`A.`) — they render as ugly identifiers.
|
|
8
|
+
|`replace`|`phases`|Replace the full list (initial setup, full restructure)|
|
|
9
|
+
|`start`|`task`|Set task to `in_progress`|
|
|
10
|
+
|`done`|`task` or `phase` (or neither = all)|Mark completed|
|
|
11
|
+
|`drop`|`task` or `phase` (or neither = all)|Mark abandoned|
|
|
12
|
+
|`rm`|`task` or `phase` (or neither = all)|Remove|
|
|
13
|
+
|`append`|`phase`, `items: {id, label}[]`|Append tasks; creates phase if missing|
|
|
14
|
+
|`note`|`task`, `text`|Append a note to `task.notes`. Only use to leave reminders for future-you.|
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
- **Task `label`**: 5–10 words, what is being done, not how.
|
|
18
|
+
- **Phase `name`**: short noun phrase prefixed with a roman numeral — `I. Foundation`, `II. Auth`, `III. Verification`. Single-phase plans still use `I.`. Never use snake_case, arabic numerals, or letter prefixes.
|
|
52
19
|
|
|
53
20
|
## Rules
|
|
54
21
|
- Mark tasks done immediately after finishing — never defer.
|
|
55
|
-
- Complete phases in order
|
|
56
|
-
- On blockers, append a new task to the active phase.
|
|
22
|
+
- Complete phases in order.
|
|
23
|
+
- On blockers, `append` a new task to the active phase.
|
|
57
24
|
- Keep ids stable once introduced.
|
|
58
|
-
</protocol>
|
|
59
25
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
4. New instructions arrive mid-task — capture before proceeding
|
|
66
|
-
</conditions>
|
|
26
|
+
## When to create a list
|
|
27
|
+
- Task requires 3+ distinct steps
|
|
28
|
+
- User explicitly requests one
|
|
29
|
+
- User provides a set of tasks to complete
|
|
30
|
+
- New instructions arrive mid-task — capture before proceeding
|
|
67
31
|
|
|
68
32
|
<examples>
|
|
69
33
|
# Initial setup (multi-phase)
|
|
@@ -81,9 +45,3 @@ Create a todo list when:
|
|
|
81
45
|
# Append tasks to a phase
|
|
82
46
|
`{"ops":[{"op":"append","phase":"II. Auth","items":[{"id":"task-8","label":"Handle retries"},{"id":"task-9","label":"Run tests"}]}]}`
|
|
83
47
|
</examples>
|
|
84
|
-
|
|
85
|
-
<avoid>
|
|
86
|
-
- Single-step tasks — act directly
|
|
87
|
-
- Conversational or informational requests
|
|
88
|
-
- Tasks completable in under 3 trivial steps
|
|
89
|
-
</avoid>
|