pi-context 2.0.0 → 2.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-context",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "Agentic Context Management for Pi",
5
5
  "files": [
6
6
  "src",
@@ -15,18 +15,19 @@
15
15
  "pi-package",
16
16
  "context-management",
17
17
  "context-optimization",
18
+ "context-compact",
18
19
  "time-travel",
19
20
  "checkpoint",
20
21
  "pi-skill"
21
22
  ],
22
23
  "type": "module",
23
- "author": "",
24
+ "author": "ttttmr",
24
25
  "license": "MIT",
25
26
  "devDependencies": {
26
- "@earendil-works/pi-ai": "^0.75.4",
27
- "@earendil-works/pi-coding-agent": "^0.75.4",
28
- "@earendil-works/pi-tui": "^0.75.4",
29
- "typescript": "^5.7.2"
27
+ "@earendil-works/pi-ai": "^0.80.6",
28
+ "@earendil-works/pi-coding-agent": "^0.80.6",
29
+ "@earendil-works/pi-tui": "^0.80.6",
30
+ "typescript": "^5.9.3"
30
31
  },
31
32
  "pi": {
32
33
  "extensions": [
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: context-management
3
- description: Use this skill for work likely to span many turns, branches, retries, research, reading several files/webpages, plan-then-execute phases, repeated cases, debugging, or interrupted/messy threads. It guides agents to maintain a clean working set with checkpoints, timeline review, and compaction at useful continuation boundaries. Usually skip for one-shot reads, bounded summaries, direct rewrites, simple lookups, or deterministic scripts.
3
+ description: "Use this skill for multi-turn, phased, or noisy work: research/reading, debugging, plan-then-execute, retries/pivots, background or asynchronous work, handoffs, user decisions, task switching, repeated items, or repeated progress checks. It keeps the conversation as a clean working set with checkpoints, timeline review, and compaction at continuation boundaries. Always use when resuming after context compaction or when a long phase reaches a decision, handoff, validation, or task-switch boundary. Usually skip simple one-shot tasks."
4
4
  ---
5
5
 
6
6
  # Context Management
7
7
 
8
- Use this skill to maintain the active conversation as a useful **working set** for the next step. The goal is not to archive more history or compress more aggressively; it is to keep raw only the context that still needs direct reasoning, and carry the rest as compact task state when that is more efficient.
8
+ Use this skill to keep the active conversation as a useful **working set** for the next step. Keep raw only the context that still needs direct reasoning; carry the rest as compact task state when that is more efficient.
9
9
 
10
10
  Core rhythm:
11
11
 
@@ -25,100 +25,95 @@ Before choosing a tool, ask:
25
25
 
26
26
  - What am I trying to do next?
27
27
  - What facts, constraints, or artifacts must stay raw for that next action?
28
- - What history is useful only as a conclusion or state update?
29
- - What history is just process noise or stale baggage?
28
+ - What important data has a reliable external source I can re-check instead of carrying raw?
29
+ - What history is useful only as a conclusion, pointer, or state update?
30
+ - What history is process noise or stale baggage?
30
31
 
31
- Classify context into three forms:
32
+ Classify context into:
32
33
 
33
- - **Raw context:** user intent, constraints, code/log/error details, evidence, or plan text that you expect to inspect directly soon.
34
- - **State summary:** decisions, findings, lessons, changed files, validation status, rejected leads, and next steps that can replace raw process.
35
- - **Discardable process:** repetitive searches, verbose logs, abandoned hypotheses, false starts, and unrelated turns whose useful value is already captured or no longer needed.
34
+ - **Raw context:** user intent, constraints, code/log/error details, evidence, or plan text you expect to inspect directly soon.
35
+ - **State summary:** decisions, findings, lessons, changed files, validation status, source pointers, rejected leads, and next steps that can replace raw process.
36
+ - **Discardable process:** repetitive searches, verbose logs, abandoned hypotheses, false starts, and unrelated turns whose useful value is already captured or gone.
36
37
 
37
38
  If the active context is already small, coherent, and directly useful for the next step, do not manage it just to be tidy.
38
39
 
39
40
  ## When to use
40
41
 
41
- Use this mode when the user is asking for work that may outgrow one clean thread:
42
+ Use this mode when the work may outgrow one clean thread:
42
43
 
43
44
  - search, research, browser work, or reading many files/logs/pages/results
44
- - several links or low-density webpages where only conclusions and next actions should survive
45
45
  - investigate -> decide -> execute -> validate
46
46
  - plan -> implement -> verify
47
- - multiple approaches, retries, failed branches, or pivots
47
+ - background or asynchronous work, handoffs, user decisions, or delayed results
48
+ - multiple approaches, retries, failed branches, comparisons, or pivots
48
49
  - repeated similar cases, tickets, reviews, or batch items
49
50
  - a main task that may be interrupted by side tasks
50
- - a scattered thread that should be cleaned up before continuing from a clean point
51
- - debugging, troubleshooting, refactoring, migration, or other code-facing work that may get noisy
51
+ - repeated progress/status checks that indicate active state is hard to track
52
+ - scattered threads that need cleanup before continuing
53
+ - debugging, troubleshooting, refactoring, migration, or code-facing work that may get noisy
52
54
 
53
- If one of these clearly applies, take a structural action now, usually a checkpoint. Do not merely describe the workflow. If the user has not yet provided enough task details, still create a checkpoint for the workflow shape before asking clarifying questions, and name the detected mode briefly (search/reading, planning, repeated batch, task switching/cleanup, development retry).
55
+ If one of these clearly applies, take a structural action now, usually a checkpoint. Do not merely describe the workflow. If the user has not provided enough task details, still checkpoint the workflow shape before asking clarifying questions.
54
56
 
55
- Usually skip this skill for one-shot reads, bounded summaries, direct rewrites, simple fact lookup, conceptual explanation, deterministic scripts, short tasks that can stay clean, or moments where the active context is already a good working set.
57
+ Usually skip this skill for one-shot reads, bounded summaries, direct rewrites, simple lookups, deterministic scripts, short tasks that can stay clean, or moments where the active context is already a good working set.
56
58
 
57
59
  ## Start-of-turn check
58
60
 
59
61
  At the start of each new user message, classify it:
60
62
 
61
- - **Same task / next phase**: continue; if the previous phase is complete and noisy, compact before the next phase.
62
- - **Correction or follow-up on the last answer**: usually answer from recent context; do not compact yet.
63
- - **New unrelated task or direction shift**: if the previous task left a complete noisy segment, inspect the timeline first when multiple checkpoints or possible anchors exist, then compact to a continuation anchor that gives the new task a clean working set.
63
+ - **Same task / next phase:** continue; if the previous phase is complete and noisy, compact before the next phase.
64
+ - **Correction or follow-up:** usually answer from recent context; do not compact yet.
65
+ - **New task or direction shift:** if the previous task left a complete noisy segment, inspect timeline when anchors are unclear, then compact to a continuation anchor that gives the new task a clean working set.
64
66
 
65
- Think of the tools as a phase pipeline: `context_checkpoint` marks useful anchors, work happens, `context_timeline` shows the structure when orientation or target choice is unclear, and `context_compact` creates a new branch from the chosen continuation anchor with a summary of what happened after it. The target is a working-set choice, not an age choice: keep raw context only when it will help the next action; summarize or drop raw process when it would distract.
66
-
67
- This prevents both premature cleanup after final answers and endless checkpoint-only behavior that lets stale work accumulate.
67
+ Think of the tools as a phase pipeline: checkpoint marks anchors, work happens, timeline shows structure, and compact creates a new branch from the chosen continuation anchor with a summary of what happened after it. The target is a working-set choice, not an age choice.
68
68
 
69
69
  ## Main loop
70
70
 
71
- 1. Before noisy work, create a semantic checkpoint as the first context-management action, even if the next visible step is asking for missing inputs. If the first job is orientation over existing history, run `context_timeline` before adding a new checkpoint.
72
- 2. When the task shape is clear, read one matching scenario reference only if it will change tool timing, anchor choice, or summary content. Skip reference loading for obvious short applications where this main skill body is enough. Do not stop after checkpoint-only unless the prompt is intentionally lightweight.
71
+ 1. Before noisy work, create a semantic checkpoint as the first context-management action. If the first job is orientation over existing history, run `context_timeline` before adding a new checkpoint.
72
+ 2. When the task shape is clear, read one matching scenario reference only if it will change tool timing, anchor choice, or summary content. Skip reference loading for obvious short applications where this main skill body is enough.
73
73
  3. Add checkpoints at meaningful milestones: phase boundaries, risky attempts, reusable batch methods, and interruptions.
74
74
  4. Use `context_timeline` when the active path structure affects the next decision or compact target.
75
- 5. At phase boundaries, run the compact gate before starting another phase. If the whole requested task is complete and only the final response remains, answer and wait; let the next user message determine whether cleanup is useful.
75
+ 5. At continuation boundaries, run the compact gate before starting another phase. If the whole requested task is complete and only the final response remains, answer and wait.
76
76
  6. After a successful compact, continue from the injected summary instead of dragging the full raw path forward.
77
77
 
78
+ ## Continuation boundaries
79
+
80
+ A continuation boundary is a point where the current phase has produced a stable result and the next action will use that result to start a different phase. It is not necessarily the end of the user's whole task.
81
+
82
+ Examples: investigation -> decision/plan/implementation, implementation -> validation, failed validation -> next approach, delayed result -> routing/action, user decision -> execution, rejected branch -> replacement direction, side request -> pause/summarize mainline before switching.
83
+
84
+ Do not ask only "is the whole task done?" Ask "will the next action start a new phase using the stable result of this phase?" If yes, this is often a compaction boundary.
85
+
86
+ Handoffs are not final answers: if a response transfers control to the user, another actor/process, later validation, or a queued phase, compact when the prior phase was noisy and the next action needs only stable state.
87
+
78
88
  ## Read the right reference
79
89
 
80
- Read **one primary reference** based on task shape when the scenario pattern will affect tool timing, anchor choice, or summary content:
90
+ Read **one primary reference** only when the scenario pattern will affect tool timing, anchor choice, or summary content:
81
91
 
82
- - search / research / reading-heavy work, especially web search, browser operation, or low-density webpages -> `references/search-research-and-reading.md`
92
+ - search / research / reading-heavy work -> `references/search-research-and-reading.md`
83
93
  - development / debugging / troubleshooting / refactoring / migration -> `references/development-and-troubleshooting.md`
84
94
  - planning / staged execution / todo-driven work -> `references/planning-and-execution.md`
85
95
  - repeated similar items / batch work -> `references/repeated-items-and-batch-work.md`
86
- - task switching / pause-resume / interruptions to a mainline task / scattered-thread cleanup-and-continue -> `references/task-switching-and-cleanup.md`
96
+ - task switching / pause-resume / interruptions / cleanup-and-continue -> `references/task-switching-and-cleanup.md`
97
+ - interleaved async work / overlapping fronts / background results / user decisions -> `references/interleaved-async-work.md`
87
98
 
88
- Also read `references/retry-branch-and-pivot.md` when multiple approaches, failed branches, comparisons, retries, or pivots become central. For code/debugging work with repeated attempts, use both `references/development-and-troubleshooting.md` and `references/retry-branch-and-pivot.md`.
99
+ Also read `references/retry-branch-and-pivot.md` when multiple approaches, failed branches, comparisons, retries, or pivots become central.
89
100
 
90
101
  ## Tool policy
91
102
 
92
103
  ### `context_checkpoint`
93
104
 
94
- Default move. Use it before noisy work, a new phase, a risky attempt, switching subtasks, or after a meaningful milestone.
95
-
96
- Use semantic names so the timeline stays readable:
97
-
98
- - `<task>-start`
99
- - `<task>-<phase>`
100
- - `<task>-<attempt>`
101
- - `<task>-<milestone>`
102
-
103
- Examples: `auth-oauth-start`, `timeout-analysis-search`, `db-migration-plan`, `parser-fix-attempt-2`.
104
-
105
- Avoid generic names like `start`, `checkpoint-1`, `phase-1`, or `retry`.
105
+ Use before noisy work, a new phase, a risky attempt, switching subtasks, or after a meaningful milestone. Use semantic names such as `<task>-start`, `<task>-<phase>`, `<task>-<attempt>`, or `<task>-<milestone>`. Avoid generic names like `start`, `checkpoint-1`, or `retry`.
106
106
 
107
107
  ### `context_timeline`
108
108
 
109
- Use it as the structural view of the active path, not only as a rescue tool:
109
+ Use it as the structural view of the active path:
110
110
 
111
111
  - when the current path shape affects the next decision
112
112
  - when several checkpoints, branches, or task switches exist
113
- - before choosing a compact target that is not obvious
113
+ - before choosing a non-obvious compact target
114
114
  - when the thread feels cluttered and you need to distinguish useful context from baggage
115
115
 
116
- When reading the timeline, ask:
117
-
118
- - What is the current task and immediate next action?
119
- - Which prior raw messages are still needed for that next action?
120
- - Which completed, failed, or unrelated paths are now baggage?
121
- - Which anchor gives the smallest sufficient working set after summary injection?
116
+ When reading the timeline, ask which raw messages are still needed for the immediate next action, which paths are now baggage, and which anchor gives the smallest sufficient working set after summary injection.
122
117
 
123
118
  ### `context_compact`
124
119
 
@@ -126,6 +121,16 @@ Use it to replace raw history with a state summary when the next phase would ben
126
121
 
127
122
  Typical compact boundaries: investigation -> execution, diagnosis -> fix, implementation -> validation, failed attempt -> next attempt, representative item -> remaining batch, completed noisy task -> new user task.
128
123
 
124
+ Strong signals to consider compaction:
125
+
126
+ - repeated progress/status checks
127
+ - inability to summarize current state, next action, and open risks in one short paragraph
128
+ - rejected, abandoned, or superseded branches
129
+ - stable result after many tool calls or long output
130
+ - returned background/asynchronous/delegated result
131
+ - material plan or approach change
132
+ - side question arriving while stale process history is active
133
+
129
134
  Do not compact while exploration is still active, when the result is unstable, just because the skill triggered, or just because the user-visible task ended.
130
135
 
131
136
  ## Compact gate
@@ -136,38 +141,25 @@ Before calling `context_compact`, require all three:
136
141
  2. You can restore the useful task state in a clear summary.
137
142
  3. There is an immediate continuation that benefits from cleaner context.
138
143
 
139
- If the compact is prompted by a new user message, a direction shift, or several possible checkpoint targets, run `context_timeline` first and choose the target from the visible structure rather than from memory.
144
+ If the compact is prompted by a new user message, a direction shift, or several possible checkpoint targets, run `context_timeline` first and choose the target from visible structure rather than memory.
140
145
 
141
- Condition 3 means the next action is a new phase, not just more of the same exploration. Examples: run the export, implement the fix, validate, process the next item, or try the chosen next approach.
146
+ If the whole task is done and only the final answer remains, wait. Compact later only if the next user message makes it useful.
142
147
 
143
- If conditions 1 and 2 are true but the whole task is done and only the final answer remains, wait. Compact later only if the next user message makes it useful.
148
+ Checkpoint-only failure mode: a checkpoint is useful because it gives you a clean anchor to compact back to later. After any checkpointed phase produces a stable result, ask what the phase settled, whether the next step is different, and whether a summary can replace the raw trail. If yes, compact; do not keep accumulating raw history just because the overall task is still active.
144
149
 
145
150
  ## Choosing target and backup
146
151
 
147
152
  Choose the continuation anchor by designing the next working set:
148
153
 
149
154
  1. Name the immediate next action.
150
- 2. Decide what must remain raw: active user intent, current constraints, still-open evidence or code context, an approved plan being executed, or details you expect to inspect directly next.
151
- 3. Decide what can become state summary or disappear: completed searches, verbose logs, failed attempts, stale branches, earlier unrelated tasks, and process details whose useful value is already clear.
155
+ 2. Decide what must remain raw: active user intent, current constraints, still-open evidence/code context, an approved plan being executed, or details you expect to inspect directly next.
156
+ 3. Decide what can become state summary or disappear: completed searches, verbose logs, failed attempts, stale branches, earlier unrelated tasks, externally recoverable data, and clear process details.
152
157
  4. Pick the anchor that leaves the new branch with the **smallest sufficient context** after summary injection.
153
- 5. If an older anchor plus a stronger summary is cleaner than a recent anchor plus stale context, prefer the older anchor.
154
-
155
- The right target may be a recent phase-start, a plan-ready checkpoint, a pre-branch checkpoint, a repeated-work baseline, an older checkpoint, or `root`. `root` is appropriate when the old path no longer contributes raw context and the summary can carry the necessary state.
156
-
157
- Avoid targets that create a poor working set:
158
+ 5. If an older anchor plus a stronger summary is cleaner than a recent anchor plus stale context, prefer the older anchor. When completed fronts fill the middle of the thread, it can be correct to compact to a much older anchor or even `root` if the summary restores the active front and source pointers.
158
159
 
159
- - too late: the new branch still contains the clutter, failed path, or unrelated task you meant to leave behind
160
- - too early with a weak summary: the next phase loses constraints, decisions, evidence, or changed-file state it needs
161
- - semantically wrong: the anchor preserves a context frame that no longer matches the current task
160
+ Avoid targets that are too late, too early with a weak summary, or semantically wrong. If there are several checkpoints, a task switch, or uncertainty about the best working set, run `context_timeline` first.
162
161
 
163
- For bounded phases, choose by what should remain raw:
164
-
165
- - target `research-start` to summarize the whole research segment
166
- - target `research-end` to keep research raw and summarize only later clutter before follow-up research
167
-
168
- If there are several checkpoints, a task switch, or any uncertainty about the best working set, run `context_timeline` first.
169
-
170
- Use `backupCheckpoint` when the raw path may still matter later: long investigations, abandoned branches, risky compactions, or details that may be needed for recovery. A backup checkpoint is a recovery safety net, not a substitute for the summary; include details likely needed in the next phase because returning to backup is costly.
162
+ Use `backupCheckpoint` when raw history may still matter later. A backup is a recovery safety net, not a substitute for the summary.
171
163
 
172
164
  ## Compact summary contract
173
165
 
@@ -180,36 +172,34 @@ A compact summary must restore:
180
172
  1. **Task state:** current task, user intent, constraints, decisions, assumptions, and known result/progress/failure.
181
173
  2. **External state:** changed files, created/deleted artifacts, running/stopped processes, browser actions, tickets/records, deployments, remote changes.
182
174
  3. **Verification state:** commands already run, validation status, notable outputs, and remaining risks or open questions.
183
- 4. **Navigation state:** source anchors/evidence when needed, rejected leads worth avoiding, backup checkpoint guidance, and the explicit next step.
184
-
185
- Include why compacting is appropriate only when it helps future orientation. Avoid vague summaries like `Done`, `Investigated`, `Switching context`, or `Going back`.
175
+ 4. **Navigation state:** source anchors/evidence when needed, rejected leads worth avoiding, backup checkpoint guidance, and explicit next step.
186
176
 
187
- Good examples:
177
+ If important data has a reliable external source, preserve the pointer and retrieval method rather than copying the raw data. Examples: file path and line/query, database table/query, task/job id, log path, URL, record id, branch/commit, or command to inspect status. Include raw values only when they are small, unstable, hard to retrieve, or needed for immediate reasoning.
188
178
 
189
- - `Current task: plan mitigation for API timeouts. State: DB pool exhaustion is the likely root cause. Evidence: logs show pool wait timeouts during peak traffic; config has pool size 10; no network errors found. Rejected lead: API gateway timeout appears downstream of DB waits. Next step: propose mitigation and validation steps.`
190
- - `Current task: validate the parser fix. State: implementation is done. External state: changed files src/parser.ts and test/parser.test.ts. Validation not yet run after the final edit. Next step: run targeted parser tests and summarize remaining edge cases. Backup: parser-fix-debug-history if exact failed attempts are needed.`
179
+ For long-running work, shape the summary as a state capsule: goal, stable result, decisions, rejected paths, current artifacts/source pointers, active work, pending input, risks/open questions, and next action. Include why compacting is appropriate only when it helps future orientation. Avoid vague summaries like `Done`, `Investigated`, `Switching context`, or `Going back`.
191
180
 
192
- Before compacting, quickly check: stable state? real continuation? anchor gives the smallest sufficient working set? summary restores state after that anchor? external side effects and validation captured? explicit next step?
181
+ Before compacting, quickly check: stable state? real continuation? smallest sufficient working set? summary restores state after the anchor? externally recoverable data represented by pointers? external side effects and validation captured? explicit next step?
193
182
 
194
183
  ## After compact
195
184
 
196
- 1. Read the injected summary carefully.
197
- 2. Treat it as the new active state.
198
- 3. Before continuing, verify it contains enough state for the next action.
199
- 4. Remember that disk and external systems were not rolled back by the context move; if state matters, inspect the current files/tools/services rather than trusting the historical anchor.
200
- 5. If a missing detail is cheap to reconstruct from disk, tools, or source anchors, retrieve it directly.
201
- 6. Return to the backup checkpoint only when the missing raw context cannot be reconstructed cheaply.
185
+ 1. Read the injected summary carefully and treat it as the new active state.
186
+ 2. Verify it contains enough state for the next action.
187
+ 3. Remember that disk and external systems were not rolled back; inspect current files/tools/services when state matters.
188
+ 4. If a missing detail is cheap to reconstruct from disk, tools, or source anchors, retrieve it directly.
189
+ 5. Return to the backup checkpoint only when the missing raw context cannot be reconstructed cheaply.
202
190
 
203
191
  ## Common mistakes
204
192
 
205
193
  Avoid:
206
194
 
207
195
  - checkpointing constantly without phase meaning
196
+ - checkpointing early but never compacting after a stable phase result
208
197
  - compacting blindly without timeline when anchor choice is unclear
209
198
  - preserving too much raw history because older anchors or `root` feel risky
210
- - using an old anchor or `root` with a weak summary that drops current task state
199
+ - using an old anchor or `root` with a weak summary
211
200
  - compacting immediately after a final deliverable when no next user intent is known
212
201
  - carrying completed noisy phases into a new task
202
+ - treating handoff or decision prompts as final answers when a continuation is expected
213
203
  - writing summaries that recap history but fail to restore current task state
214
204
  - assuming compact or branch navigation reverts files, processes, browser state, or remote services
215
205
  - omitting decisions, constraints, external side effects, changed files, validation status, or next step
@@ -0,0 +1,143 @@
1
+ # Interleaved Async Work
2
+
3
+ Use this reference when the hard part is **not** the external worker itself, but the current agent carrying several overlapping lines of work in one conversation.
4
+
5
+ Common examples:
6
+
7
+ - a main task continues while background jobs, subagents, reviewers, or tools may return later
8
+ - the user asks side questions while another front is still active
9
+ - progress updates, returned results, decisions, and new work are interleaved in the same thread
10
+ - several pending fronts have different next actions, and raw history starts making the current state hard to see
11
+
12
+ This is context management for the current agent. It is not a subagent-management policy. The goal is to keep the current working set clear enough to answer: **what am I doing now, what is parked, what just returned, and what raw context is still needed?**
13
+
14
+ ## Mental model: fronts
15
+
16
+ Treat each overlapping line of work as a **front**.
17
+
18
+ A front may be:
19
+
20
+ - the current user-facing task
21
+ - a paused mainline task
22
+ - a background command or long-running job
23
+ - a subagent/reviewer/collaborator result that may return later
24
+ - a pending user decision
25
+ - a side request that should be answered before resuming the mainline
26
+
27
+ For each front, keep only one of these in the active working set:
28
+
29
+ - **Active raw front:** the thing you are reasoning about right now; keep necessary raw details.
30
+ - **Parked state capsule:** a paused or waiting front summarized by goal, current state, source pointers, next action, and blockers.
31
+ - **Stale process:** old logs, retries, status chatter, and abandoned paths whose lesson has already been captured.
32
+
33
+ The mistake to avoid is carrying every front raw at once.
34
+
35
+ ## Working pattern
36
+
37
+ 1. Identify the active front before each substantial reply or tool call.
38
+ 2. If another front is still pending, keep it as a small state capsule rather than raw history.
39
+ 3. When a result returns, capture it into the relevant front before responding.
40
+ 4. If the returned result does not become the active front immediately, park it as state and preserve the user's current focus.
41
+ 5. Before switching fronts, compact if the old front's raw process is now stale and the next front can continue from a summary.
42
+ 6. If several fronts are tangled, run `context_timeline` to find the clean anchor and separate active, parked, completed, and stale paths.
43
+
44
+ ## What to record per parked front
45
+
46
+ Use a short capsule:
47
+
48
+ - Front: short name for this line of work
49
+ - Goal: what this front is trying to accomplish
50
+ - State: waiting / running / returned / blocked / ready for next phase
51
+ - Latest stable result: what is known now
52
+ - Source pointers: files, links, task ids, log paths, branches, records, queries, or commands that identify where to re-check details
53
+ - Decisions and constraints: choices already made that still matter
54
+ - Rejected paths: approaches that should not be repeated
55
+ - Pending input or trigger: what would make this front active again
56
+ - Next action: what to do when resuming this front
57
+
58
+ This capsule is for future-you, not for the external worker. It should be enough to resume without rereading the interleaved raw thread.
59
+
60
+ If a front's detailed state is available from a reliable external source, keep the pointer, not the dump. For example, store the task id plus the command/log path to inspect it, not pages of status output; store the database query or record id, not every row; store the file path and relevant section, not the whole file. Copy raw details only when they are small, volatile, hard to retrieve, or needed for immediate reasoning.
61
+
62
+ ## When to compact
63
+
64
+ Compact when interleaving has made raw context a worse working set:
65
+
66
+ - you are switching from one front to another after a noisy phase
67
+ - a side request arrives while the mainline is noisy but resumable from a capsule
68
+ - a background/subagent/reviewer/tool result returned and its raw logs are no longer needed
69
+ - the user has asked for status more than once and you cannot state all active fronts briefly
70
+ - a front was rejected, superseded, completed, or parked indefinitely
71
+ - the next action belongs to a different front than the recent raw history
72
+ - the active front started much earlier, and the middle of the thread is mostly completed or unrelated fronts
73
+
74
+ Do **not** compact just because async work exists. Compact when a front can safely be represented as state while another front becomes active.
75
+
76
+ ## Choosing how far back to compact
77
+
78
+ Interleaved work often makes recent anchors poor targets: they may preserve the completed fronts that happened after the active front was launched. Be willing to compact aggressively when the summary can restore state.
79
+
80
+ A compact to an old anchor or even `root` is appropriate when:
81
+
82
+ - the active front can be described by a concise capsule
83
+ - completed fronts between the anchor and now no longer need raw context
84
+ - important details are recoverable from reliable source pointers
85
+ - the next action does not require inspecting the interleaved raw discussion
86
+ - you can name what remains active, what is parked, and what is done
87
+
88
+ Use a backup checkpoint for safety when the interleaved raw path may still matter, but do not keep it active just because it is long.
89
+
90
+ Before a deep compact, ask:
91
+
92
+ ```text
93
+ Active now: which front am I resuming?
94
+ Parked: which fronts still wait for input/result?
95
+ Done: which fronts can be summarized or omitted?
96
+ Pointers: where can I re-check authoritative details?
97
+ Next: what is the immediate action after compacting?
98
+ ```
99
+
100
+ ## Handling returned results
101
+
102
+ When a delayed result appears in the middle of another thread:
103
+
104
+ 1. **Capture:** identify which front it belongs to and summarize its result.
105
+ 2. **Classify:** progress, stable completion, failure, decision needed, or noise.
106
+ 3. **Choose focus:** decide whether this result should interrupt the current active front. If not, park it.
107
+ 4. **Compact if needed:** if switching to it or away from it would drag stale logs/retries forward, compact first.
108
+ 5. **Continue:** resume the chosen active front from a clean working set.
109
+
110
+ ## Example capsules
111
+
112
+ ```text
113
+ Front: import-test-flake
114
+ Goal: fix flaky import tests.
115
+ State: reviewer returned findings.
116
+ Latest stable result: fixed sleeps were rejected; signed retry strategy is still viable.
117
+ Source pointers: branch retry-import-tests, log tmp/import-flake.log.
118
+ Pending input or trigger: decide whether to implement bounded retries.
119
+ Next action: if accepted, implement bounded retry and rerun targeted tests.
120
+ ```
121
+
122
+ ```text
123
+ Front: docs-build
124
+ Goal: validate generated documentation before publishing.
125
+ State: background build running.
126
+ Latest stable result: source edits complete; validation not yet known.
127
+ Source pointers: task docs-build, output dist/docs/.
128
+ Pending input or trigger: build exit status.
129
+ Next action: on success, summarize validation; on failure, inspect first build/link error.
130
+ ```
131
+
132
+ ## Common mistakes
133
+
134
+ Avoid:
135
+
136
+ - treating async/subagent management as the goal instead of keeping the current agent's working set clear
137
+ - carrying several fronts raw at once
138
+ - copying externally recoverable status dumps instead of preserving reliable source pointers
139
+ - letting a returned result overwrite the user's current active request without deciding focus
140
+ - reporting status repeatedly while the real problem is that fronts are not summarized
141
+ - compacting away a front without preserving how to resume it
142
+ - avoiding a deep compact even though source pointers and capsules can restore the active state
143
+ - resuming from memory when a small front capsule would be safer
@@ -33,6 +33,14 @@ Compact when:
33
33
  - the direction changed enough that the old path is now baggage
34
34
  - the next attempt should start from a focused state rather than the raw failed branch
35
35
 
36
+ When compacting after an abandoned branch, preserve:
37
+
38
+ - what was tried
39
+ - why it failed or was rejected
40
+ - what should not be repeated
41
+ - what remains valid
42
+ - the chosen next approach
43
+
36
44
  ## Strategy pivot
37
45
 
38
46
  Use this pattern when the old direction no longer makes sense even though the task is still continuing.
@@ -56,7 +64,7 @@ context_checkpoint({ name: "oauth-fix-start" });
56
64
 
57
65
  context_compact({
58
66
  target: "oauth-fix-start",
59
- summary: "Current task: continue the OAuth fix with a new approach. State: cookie-based approach is not viable because the callback flow loses session continuity. Decision: switch to signed state tokens. Next step: implement the signed-state approach.",
67
+ summary: "Current task: continue the OAuth fix with a new approach. State: cookie-based approach is not viable because the callback flow loses session continuity. Rejected path: do not repeat cookie-based continuity for this flow. Still valid: callback validation and provider config findings. Decision: switch to signed state tokens. Next step: implement the signed-state approach.",
60
68
  backupCheckpoint: "oauth-cookie-approach-history"
61
69
  });
62
70
  context_checkpoint({ name: "oauth-signed-state-start" });
@@ -67,5 +75,6 @@ context_checkpoint({ name: "oauth-signed-state-start" });
67
75
  Avoid:
68
76
  - opening alternative branches without a clean checkpoint first
69
77
  - dragging failed branches forward after their lesson is already clear
78
+ - omitting the rejected path, failure reason, or chosen replacement from the compact summary
70
79
  - compacting to a point that still includes the branch you meant to abandon
71
80
  - treating every branch as equally worth preserving
@@ -27,9 +27,10 @@ Use when the thread is already stale or messy and you want to compress it now, e
27
27
  2. Before switching away or compacting a noisy path, preserve or choose the anchor that will give the resumed/new task a clean working set.
28
28
  3. If needed, create a backup checkpoint for the current noisy branch.
29
29
  4. If the user has just started a new task after a completed noisy task, compact before doing the new task so the completed task becomes a compact summary rather than active baggage.
30
- 5. Handle the side task or cleanup move.
31
- 6. Compact away the stale path when the handoff summary is clear.
32
- 7. Resume from the paused anchor or continue from the compacted state.
30
+ 5. If the user asks a concrete side question while noisy mainline work is active, pause or summarize the active work, compact if the raw mainline history is no longer needed for the side question, answer the side question, and preserve how to resume the paused work.
31
+ 6. Handle the side task or cleanup move.
32
+ 7. Compact away the stale path when the handoff summary is clear.
33
+ 8. Resume from the paused anchor or continue from the compacted state.
33
34
 
34
35
  ## Useful anchors
35
36
 
package/src/index.ts CHANGED
@@ -22,6 +22,8 @@ interface SessionTreeNode {
22
22
  }
23
23
 
24
24
  const InternalTools = ["context_checkpoint", "context_timeline", "context_compact"];
25
+ const PiContextCustomMessageType = "pi-context";
26
+ const AcmEnableFollowUp = "Agentic context management is now enabled";
25
27
  let CommandCtx: ExtensionCommandContext | null = null;
26
28
  let CompactParams: any = null;
27
29
 
@@ -392,7 +394,11 @@ export default function (pi: ExtensionAPI) {
392
394
  parameters: ContextCompactParams,
393
395
  async execute(_id, params: Static<typeof ContextCompactParams>, _signal, _onUpdate, ctx) {
394
396
  if (!CommandCtx) {
395
- ctx.ui.setEditorText(`/acm ${ctx.ui.getEditorText() || "continue"}`)
397
+ const editorText = ctx.ui.getEditorText();
398
+ const followUp = editorText
399
+ ? `${AcmEnableFollowUp}\n${editorText}`
400
+ : AcmEnableFollowUp;
401
+ ctx.ui.setEditorText(`/acm ${followUp}`)
396
402
  return {
397
403
  content: [{
398
404
  type: "text",
@@ -418,9 +424,7 @@ export default function (pi: ExtensionAPI) {
418
424
 
419
425
  const enrichedMessage = `(handoff summary from ${origin})\n${params.summary}`;
420
426
 
421
- const nid = await sm.branchWithSummary(tid, enrichedMessage);
422
427
  CompactParams = params;
423
- CompactParams.nid = nid;
424
428
  CompactParams.tid = tid;
425
429
  CompactParams.enrichedMessage = enrichedMessage;
426
430
  CompactParams.usageBeforeText = usageBeforeText;
@@ -436,7 +440,7 @@ export default function (pi: ExtensionAPI) {
436
440
  ctx.abort()
437
441
  });
438
442
 
439
- pi.on("agent_end", async () => {
443
+ pi.on("agent_end", async (_event, ctx) => {
440
444
  if (!CompactParams) {
441
445
  return
442
446
  }
@@ -444,9 +448,11 @@ export default function (pi: ExtensionAPI) {
444
448
  return
445
449
  }
446
450
 
451
+ const sm = ctx.sessionManager as SessionManager;
447
452
  const compactParams = CompactParams;
448
453
  const commandCtx = CommandCtx;
449
454
  CompactParams = null;
455
+ const compactTurnLeaf = sm.getLeafId();
450
456
 
451
457
  // `agent_end` is emitted before the core Agent is actually idle. If we
452
458
  // call pi.sendMessage({ triggerTurn: true }) inside this handler, pi still
@@ -456,6 +462,30 @@ export default function (pi: ExtensionAPI) {
456
462
  setTimeout(async () => {
457
463
  try {
458
464
  await commandCtx.waitForIdle();
465
+
466
+ const currentLeaf = sm.getLeafId();
467
+ if (currentLeaf !== compactTurnLeaf) {
468
+ commandCtx.ui.notify("context_compact cancelled: conversation advanced before compaction completed.", "warning");
469
+ pi.sendMessage({
470
+ customType: PiContextCustomMessageType,
471
+ content: [
472
+ "context_compact cancelled: conversation advanced before the summary branch was created.",
473
+ "No compaction was applied; continue from the current path. If still useful, inspect timeline and retry with an updated summary.",
474
+ ].join("\n"),
475
+ display: false,
476
+ }, {
477
+ triggerTurn: true,
478
+ deliverAs: "followUp",
479
+ });
480
+ return;
481
+ }
482
+
483
+ const nid = sm.branchWithSummary(compactParams.tid, compactParams.enrichedMessage);
484
+ compactParams.nid = nid;
485
+ // branchWithSummary advances the leaf to the summary entry. Reset
486
+ // it so navigateTree(nid) can rebuild agent state instead of
487
+ // returning early as a no-op.
488
+ sm.branch(compactParams.tid);
459
489
  await commandCtx.navigateTree(compactParams.nid, {
460
490
  summarize: false,
461
491
  });
@@ -469,7 +499,7 @@ export default function (pi: ExtensionAPI) {
469
499
  ].join("\n"), "info");
470
500
 
471
501
  pi.sendMessage({
472
- customType: "pi-context",
502
+ customType: PiContextCustomMessageType,
473
503
  content: "context_compact complete. A handoff summary of your previous conversation path was injected above. Read it to understand your new state. Execute the Next Step from the summary",
474
504
  display: false,
475
505
  }, {
@@ -477,7 +507,19 @@ export default function (pi: ExtensionAPI) {
477
507
  deliverAs: "followUp",
478
508
  });
479
509
  } catch (err) {
480
- commandCtx.ui.notify(`context_compact failed to continue: ${err instanceof Error ? err.message : String(err)}`, "error");
510
+ const message = err instanceof Error ? err.message : String(err);
511
+ commandCtx.ui.notify(`context_compact failed: ${message}`, "error");
512
+ pi.sendMessage({
513
+ customType: PiContextCustomMessageType,
514
+ content: [
515
+ `context_compact failed: ${message}`,
516
+ "No compaction was applied; continue from the current path. Retry only with a fresh timeline/summary.",
517
+ ].join("\n"),
518
+ display: false,
519
+ }, {
520
+ triggerTurn: true,
521
+ deliverAs: "followUp",
522
+ });
481
523
  }
482
524
  }, 0);
483
525
  });