pi-session-continuity 0.1.0 → 0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1 — 2026-07-09
4
+
5
+ - Change the default automatic threshold from 75% to 70% to reduce immediate contention with Pi native auto-compaction thresholds.
6
+ - Warn on session load when native Pi auto-compaction is still enabled while Pi Session Continuity automatic behavior is enabled.
7
+ - Document the recommended project-local Pi setting `compaction.enabled=false` for projects that want Pi Session Continuity to own automatic handoffs.
8
+
3
9
  ## 0.1.0 — 2026-07-09
4
10
 
5
11
  - Add Pi package manifest for `pi-session-continuity`.
package/README.md CHANGED
@@ -49,7 +49,7 @@ pi install npm:pi-session-continuity
49
49
  Pinned GitHub install:
50
50
 
51
51
  ```bash
52
- pi install git:github.com/bernardofortes/pi-session-continuity@v0.1.0
52
+ pi install git:github.com/bernardofortes/pi-session-continuity@v0.1.1
53
53
  ```
54
54
 
55
55
  For local development only:
@@ -92,7 +92,7 @@ Defaults:
92
92
  ```json
93
93
  {
94
94
  "enabled": true,
95
- "triggerAtPercent": 75,
95
+ "triggerAtPercent": 70,
96
96
  "keepRecentPercent": 20,
97
97
  "synthesisModel": "inherit",
98
98
  "synthesisEffort": "medium",
@@ -104,6 +104,22 @@ Defaults:
104
104
 
105
105
  In interactive Pi sessions, `/continuity settings` can update this file for the public config fields. In non-interactive contexts, edit the JSON directly or run `/continuity settings` for textual inspection.
106
106
 
107
+ ### Native Pi auto-compaction
108
+
109
+ Pi native auto-compaction is enabled by default. When Pi Session Continuity automatic behavior is enabled, the package warns on session load if native Pi auto-compaction is still enabled because both systems can compete near the same context threshold.
110
+
111
+ Recommended project-local Pi setting:
112
+
113
+ ```json
114
+ {
115
+ "compaction": {
116
+ "enabled": false
117
+ }
118
+ }
119
+ ```
120
+
121
+ Save that in `<workspace>/<CONFIG_DIR_NAME>/settings.json` (normally `.pi/settings.json`). Pi Session Continuity does not change this setting automatically during install or load.
122
+
107
123
  ## Artifact layout
108
124
 
109
125
  ```text
@@ -136,7 +152,7 @@ npm pack --dry-run
136
152
 
137
153
  `npm run smoke:manual` prints a checklist template for the required clean Pi smoke assertions. The checklist must be executed from a clean Pi install pinned to a GitHub ref before public announcement. Record the Pi version, Node version, OS, install command, smoke transcript, and resulting artifact path.
138
154
 
139
- External validation commands such as `pi install git:github.com/bernardofortes/pi-session-continuity@v0.1.0`, git tags, releases, npm publishing, or uploads require separate explicit human approval.
155
+ External validation commands such as `pi install git:github.com/bernardofortes/pi-session-continuity@v0.1.1`, git tags, releases, npm publishing, or uploads require separate explicit human approval.
140
156
 
141
157
  ## Known limitations in v0.1.0
142
158
 
@@ -152,6 +168,7 @@ External validation commands such as `pi install git:github.com/bernardofortes/p
152
168
  - Synthesis failure: no resume prompt is queued; inspect the failed artifact path if one was written.
153
169
  - Write failure: no resume prompt is queued; fix filesystem permissions or artifact path.
154
170
  - Stale pending artifact: `/continuity status` reports it as inert; v0.1.0 will not silently inject it after reload.
171
+ - Native Pi auto-compaction warning: add project-local Pi settings with `compaction.enabled=false` if Pi Session Continuity should own automatic threshold handoffs. Manual `/compact` remains available.
155
172
  - Untrusted project: trust the project before relying on project-local config or automatic behavior.
156
173
 
157
174
  ## Update / uninstall
@@ -161,7 +178,7 @@ pi update --extension npm:pi-session-continuity
161
178
  pi remove npm:pi-session-continuity
162
179
 
163
180
  # For pinned GitHub installs:
164
- pi update --extension git:github.com/bernardofortes/pi-session-continuity@v0.1.0
181
+ pi update --extension git:github.com/bernardofortes/pi-session-continuity@v0.1.1
165
182
  pi remove git:github.com/bernardofortes/pi-session-continuity
166
183
  ```
167
184
 
@@ -79,7 +79,7 @@ Default threshold config:
79
79
 
80
80
  ```json
81
81
  {
82
- "triggerAtPercent": 75,
82
+ "triggerAtPercent": 70,
83
83
  "keepRecentPercent": 20
84
84
  }
85
85
  ```
@@ -90,6 +90,8 @@ Default threshold config:
90
90
 
91
91
  v0.1.0 may request native Pi compaction as token hygiene only after the Continuity Brief has been written. It must not treat native compaction proof as the source of continuity.
92
92
 
93
+ Because Pi native auto-compaction is enabled by default, Pi Session Continuity must warn on session load when native Pi auto-compaction is still enabled while Pi Session Continuity automatic behavior is enabled. The warning must explain that native auto-compaction can compete with Continuity Handoff triggers and recommend disabling native auto-compaction in project-local Pi settings (`<workspace>/<CONFIG_DIR_NAME>/settings.json`) by setting `compaction.enabled` to `false`. The extension must not silently mutate Pi settings during install or load.
94
+
93
95
  Continuity Brief synthesis must reserve enough output budget for reasoning-capable models so effort tokens do not starve the final Markdown body. If threshold-triggered synthesis fails, automatic behavior should not retry on every subsequent turn; it should cool down and leave manual `/continuity checkpoint` available.
94
96
 
95
97
  ### v0.2+: later enhancements
@@ -108,7 +110,7 @@ Configuration should stay small for v0.1.0:
108
110
  ```json
109
111
  {
110
112
  "enabled": true,
111
- "triggerAtPercent": 75,
113
+ "triggerAtPercent": 70,
112
114
  "keepRecentPercent": 20,
113
115
  "synthesisModel": "inherit",
114
116
  "synthesisEffort": "medium",
@@ -190,7 +192,7 @@ synthesisModel: "resolved-provider/model"
190
192
  synthesisEffort: "medium"
191
193
  tokenCountAtTrigger: 0
192
194
  contextWindow: 0
193
- triggerAtPercent: 75
195
+ triggerAtPercent: 70
194
196
  keepRecentPercent: 20
195
197
  branchLeafBefore: "entry-id-or-null"
196
198
  ---
@@ -327,12 +329,12 @@ The injected prompt must include the saved Continuity Brief content read from di
327
329
 
328
330
  All user-visible messages should be short, verifiable, and product-prefixed. In interactive Pi TUI mode, detailed `/continuity status` and `/continuity settings` output should be rendered as intentional user-facing output, not as a persistent oversized widget or long background/internal-looking chatter. Notifications should not escalate to warning severity unless the headline is actually disabled, invalid, failed, or otherwise unsafe.
329
331
 
330
- The output should use human-readable labels only for the normal status panel. Do not repeat the same values in a separate diagnostics block; concrete paths that matter to the user, such as the artifact directory or last artifact path, should appear once in the main panel. Persistent footer/status-line text should stay compact, for example `Session Continuation @ 75%`, so it does not crowd the terminal footer.
332
+ The output should use human-readable labels only for the normal status panel. Do not repeat the same values in a separate diagnostics block; concrete paths that matter to the user, such as the artifact directory or last artifact path, should appear once in the main panel. Persistent footer/status-line text should stay compact, for example `Session Continuation @ 70%`, so it does not crowd the terminal footer.
331
333
 
332
334
  Idle/enabled:
333
335
 
334
336
  ```text
335
- Pi Session Continuity: enabled · trigger 75% · keep 20%.
337
+ Pi Session Continuity: enabled · trigger 70% · keep 20%.
336
338
  ```
337
339
 
338
340
  Explicitly disabled:
@@ -401,6 +403,12 @@ Invalid config:
401
403
  Pi Session Continuity disabled: invalid configuration in <path>.
402
404
  ```
403
405
 
406
+ Native Pi auto-compaction also enabled:
407
+
408
+ ```text
409
+ Pi Session Continuity warning: native Pi auto-compaction is still enabled and can compete with Continuity Handoff triggers. Recommended project setting: compaction.enabled=false in <CONFIG_DIR_NAME>/settings.json.
410
+ ```
411
+
404
412
  ## 12. Slash commands
405
413
 
406
414
  v0.1.0 commands:
@@ -541,7 +549,7 @@ Minimum Pi smoke checks must be represented by a runnable script or documented m
541
549
  3. `required-identity-present`: artifact includes `eventId`, `sessionId`, `sessionFile`, `createdAt`, and `updatedAt`.
542
550
  4. `reload-stale-is-inert`: reload does not inject a stale pending artifact; status reports it as inert.
543
551
  5. `duplicate-trigger-single-flight`: duplicate trigger while a handoff is active creates one artifact and one lock only.
544
- 6. `threshold-percent-model-change`: threshold math preserves 75% trigger intent across at least two model context windows.
552
+ 6. `threshold-percent-model-change`: threshold math preserves 70% trigger intent across at least two model context windows.
545
553
  7. `synthesis-failure-no-prompt`: forced synthesis failure queues no resume prompt and reports failure.
546
554
  8. `write-failure-no-prompt`: forced artifact write failure queues no resume prompt and reports failure.
547
555
  9. `cross-session-rejected`: artifact from another `sessionId` is not used automatically.
@@ -612,7 +620,7 @@ Dependency placement must follow Pi package rules:
612
620
  Implementation must bind the product behavior to explicit Pi APIs:
613
621
 
614
622
  - Register one command, `continuity`, and dispatch subcommands from its args so users invoke `/continuity status`, `/continuity checkpoint`, and `/continuity settings`.
615
- - Use `session_start` to initialize session-scoped state, inspect stale same-session pending artifacts, and set visible status when UI is available.
623
+ - Use `session_start` to initialize session-scoped state, inspect stale same-session pending artifacts, warn when native Pi auto-compaction is still enabled while Pi Session Continuity automatic behavior is enabled, and set visible status when UI is available.
616
624
  - Use `turn_end` or another documented low-risk post-turn event for automatic threshold checks. The threshold calculation must use `ctx.getContextUsage()` and the active model context window; if usage or model metadata is unavailable, automatic behavior skips with a visible/debuggable reason.
617
625
  - Use a single-flight in-memory latch plus the on-disk lock sentinel before synthesis starts.
618
626
  - Use `ctx.sessionManager.getSessionId()`, `ctx.sessionManager.getSessionFile()`, `ctx.sessionManager.getLeafId()`, and `ctx.sessionManager.getBranch()` when constructing artifact identity and synthesis input.
@@ -0,0 +1,157 @@
1
+ # v0.1.0 Release Validation — 2026-07-09
2
+
3
+ Scope: `pi-session-continuity` v0.1.0 public GitHub tag and npm publish readiness.
4
+
5
+ ## Release refs
6
+
7
+ - GitHub repository: `https://github.com/bernardofortes/pi-session-continuity`
8
+ - Branch commit before tag: `7c120ec Prepare v0.1.0 public release docs`
9
+ - Tag: `v0.1.0`
10
+ - Remote tag check: `git ls-remote --tags origin v0.1.0` returned `refs/tags/v0.1.0`.
11
+
12
+ ## Local package gates
13
+
14
+ Command set:
15
+
16
+ ```bash
17
+ npm test
18
+ npm run typecheck
19
+ npm pack --dry-run
20
+ npm publish --dry-run
21
+ ```
22
+
23
+ Observed results:
24
+
25
+ - `npm test`: PASS — 8 test files, 54 tests.
26
+ - `npm run typecheck`: PASS — `tsc --noEmit`.
27
+ - `npm pack --dry-run`: PASS — package `pi-session-continuity@0.1.0`, 29 files.
28
+ - `npm publish --dry-run`: PASS — package contents accepted by npm dry-run.
29
+
30
+ ## Clean GitHub tag install smoke
31
+
32
+ Used temporary Pi agent/project/session directories so the smoke did not depend on the local/default Pi profile.
33
+
34
+ ### Install/list/load
35
+
36
+ ```bash
37
+ agent_dir=$(mktemp -d /tmp/psc-clean-agent-XXXXXX)
38
+ repo='git:github.com/bernardofortes/pi-session-continuity@v0.1.0'
39
+ PI_CODING_AGENT_DIR="$agent_dir" pi install "$repo" --no-approve
40
+ PI_CODING_AGENT_DIR="$agent_dir" pi list | grep -A2 -F 'pi-session-continuity'
41
+ PI_CODING_AGENT_DIR="$agent_dir" pi --no-session -p 'Reply with exactly PSC_SMOKE_OK.'
42
+ ```
43
+
44
+ Environment:
45
+
46
+ - OS: `Linux trader 5.15.0-185-generic #195-Ubuntu SMP Fri Jun 19 17:11:50 UTC 2026 x86_64 GNU/Linux`
47
+ - Node: `v22.22.2`
48
+ - Pi: `0.80.3`
49
+ - Temporary agent dir: `/tmp/psc-clean-agent-IPTbLH`
50
+
51
+ Observed output:
52
+
53
+ ```text
54
+ Installed git:github.com/bernardofortes/pi-session-continuity@v0.1.0
55
+ git:github.com/bernardofortes/pi-session-continuity@v0.1.0
56
+ /tmp/psc-clean-agent-IPTbLH/git/github.com/bernardofortes/pi-session-continuity
57
+ PSC_SMOKE_OK
58
+ ```
59
+
60
+ Result: PASS for clean install/load from GitHub tag.
61
+
62
+ ### Command/status/config/remove assertions
63
+
64
+ Temporary paths:
65
+
66
+ - Project root: `/tmp/psc-smoke-root-odHazM`
67
+ - Agent dir: `/tmp/psc-smoke-agent-Iq2Iyu`
68
+
69
+ Observed `/continuity status` output included:
70
+
71
+ ```text
72
+ Pi Session Continuity: enabled · trigger 75% · keep 20%.
73
+ - Mode: Enabled
74
+ - Artifacts: /tmp/psc-smoke-root-odHazM/.pi/session-continuity
75
+ ```
76
+
77
+ Invalid config smoke used `.pi/session-continuity.json` with `keepRecentPercent >= triggerAtPercent` and observed:
78
+
79
+ ```text
80
+ Pi Session Continuity disabled: invalid configuration in /tmp/psc-smoke-root-odHazM/.pi/session-continuity.json.
81
+ - Mode: Disabled
82
+ - Disabled reason: invalid configuration in /tmp/psc-smoke-root-odHazM/.pi/session-continuity.json
83
+ ```
84
+
85
+ Remove smoke observed:
86
+
87
+ ```text
88
+ Removed git:github.com/bernardofortes/pi-session-continuity@v0.1.0
89
+ remove_passed
90
+ ```
91
+
92
+ ### Manual checkpoint artifact smoke
93
+
94
+ `/continuity checkpoint` must run with a persisted Pi session. A `--no-session` smoke is invalid for this assertion because Continuity Brief identity requires a concrete `sessionFile`.
95
+
96
+ Temporary paths:
97
+
98
+ - Project root: `/tmp/psc-smoke2-root-04mfOn`
99
+ - Agent dir: `/tmp/psc-smoke2-agent-b9LmdC`
100
+ - Session dir: `/tmp/psc-smoke2-sessions-Cys5kD`
101
+
102
+ Command:
103
+
104
+ ```bash
105
+ PI_CODING_AGENT_DIR="$agent_dir" pi --session-dir "$session_dir" --approve -p '/continuity checkpoint'
106
+ ```
107
+
108
+ Observed artifact:
109
+
110
+ ```text
111
+ /tmp/psc-smoke2-root-04mfOn/.pi/session-continuity/019f481c-8aaa-7b63-8eda-edeb92428a22/archive/2026-07-09T18-22-26-111Z-d3d30593-cd25-46ad-b10d-c7dff0e0736c.md
112
+ ```
113
+
114
+ Observed artifact fields:
115
+
116
+ ```text
117
+ status: "archived"
118
+ sessionFile: "/tmp/psc-smoke2-sessions-Cys5kD/2026-07-09T18-20-57-898Z_019f481c-8aaa-7b63-8eda-edeb92428a22.jsonl"
119
+ # Continuity Brief
120
+ ```
121
+
122
+ Result: PASS for checkpoint artifact creation and archive from GitHub tag in a persisted session.
123
+
124
+ ## npm publish status
125
+
126
+ `npm publish --dry-run` passed before release. The first manual publish attempts were blocked until npm authentication and a token with explicit 2FA-bypass publish permission were available.
127
+
128
+ Final publish command was run from the exact GitHub release tag:
129
+
130
+ ```bash
131
+ git checkout v0.1.0
132
+ NPM_CONFIG_USERCONFIG=/tmp/npmrc-publish npm publish --access public
133
+ git checkout main
134
+ rm -f /tmp/npmrc-publish
135
+ ```
136
+
137
+ Observed publish output:
138
+
139
+ ```text
140
+ + pi-session-continuity@0.1.0
141
+ ```
142
+
143
+ Registry verification:
144
+
145
+ ```bash
146
+ npm view pi-session-continuity@0.1.0 name version description
147
+ ```
148
+
149
+ Observed output:
150
+
151
+ ```text
152
+ name = 'pi-session-continuity'
153
+ version = '0.1.0'
154
+ description = 'Keep long-running Pi coding sessions recoverable with dull, durable handoffs.'
155
+ ```
156
+
157
+ Result: PASS — npm package `pi-session-continuity@0.1.0` is published and visible in the npm registry.
@@ -5,6 +5,7 @@ import {
5
5
  } from "@earendil-works/pi-coding-agent";
6
6
  import { Text } from "@earendil-works/pi-tui";
7
7
  import {
8
+ detectNativeAutoCompaction,
8
9
  loadConfig,
9
10
  publicConfigFromResolved,
10
11
  validateConfigDraftForPath,
@@ -73,6 +74,22 @@ export default function sessionContinuityExtension(pi: ExtensionAPI) {
73
74
  return currentConfig;
74
75
  }
75
76
 
77
+ function warnIfNativeAutoCompactionEnabled(
78
+ ctx: ExtensionContext,
79
+ config: ResolvedContinuityConfig,
80
+ ): void {
81
+ if (!config.enabled || !config.valid || !config.trusted) return;
82
+ const nativeCompaction = detectNativeAutoCompaction(
83
+ ctx.cwd,
84
+ config.trusted,
85
+ );
86
+ if (!nativeCompaction.enabled) return;
87
+ ctx.ui.notify(
88
+ `${PRODUCT_NAME} warning: native Pi auto-compaction is still enabled and can compete with Continuity Handoff triggers. Recommended project setting: compaction.enabled=false in ${CONFIG_DIR_NAME}/settings.json.`,
89
+ "warning",
90
+ );
91
+ }
92
+
76
93
  async function saveConfigDraft(
77
94
  ctx: ExtensionContext,
78
95
  draft: ContinuityConfig,
@@ -214,6 +231,7 @@ export default function sessionContinuityExtension(pi: ExtensionAPI) {
214
231
  "warning",
215
232
  );
216
233
  }
234
+ warnIfNativeAutoCompactionEnabled(ctx, config);
217
235
  notifyStatus(ctx, statusHeadlineForConfig(config));
218
236
  });
219
237
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-session-continuity",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Keep long-running Pi coding sessions recoverable with dull, durable handoffs.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/config.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import { dirname, isAbsolute, join, relative, resolve } from "node:path";
4
- import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
4
+ import {
5
+ getAgentDir,
6
+ SettingsManager,
7
+ type ExtensionContext,
8
+ } from "@earendil-works/pi-coding-agent";
5
9
  import {
6
10
  DEFAULT_ARTIFACT_DIRECTORY,
7
11
  DEFAULT_KEEP_RECENT_PERCENT,
@@ -36,6 +40,13 @@ export interface ResolvedContinuityConfig extends ContinuityConfig {
36
40
  errors: string[];
37
41
  }
38
42
 
43
+ export interface NativeCompactionStatus {
44
+ enabled: boolean;
45
+ reserveTokens: number;
46
+ keepRecentTokens: number;
47
+ errors: string[];
48
+ }
49
+
39
50
  export const DEFAULT_CONFIG: ContinuityConfig = {
40
51
  enabled: true,
41
52
  triggerAtPercent: DEFAULT_TRIGGER_AT_PERCENT,
@@ -336,6 +347,26 @@ export async function loadConfig(
336
347
  return loadConfigFromDisk(ctx.cwd, configDirName, ctx.isProjectTrusted());
337
348
  }
338
349
 
350
+ export function detectNativeAutoCompaction(
351
+ cwd: string,
352
+ projectTrusted: boolean,
353
+ agentDir = getAgentDir(),
354
+ ): NativeCompactionStatus {
355
+ const settingsManager = SettingsManager.create(cwd, agentDir, {
356
+ projectTrusted,
357
+ });
358
+ const settings = settingsManager.getCompactionSettings();
359
+ const errors = settingsManager
360
+ .drainErrors()
361
+ .map(({ scope, error }) => `${scope}: ${error.message}`);
362
+ return {
363
+ enabled: settings.enabled,
364
+ reserveTokens: settings.reserveTokens,
365
+ keepRecentTokens: settings.keepRecentTokens,
366
+ errors,
367
+ };
368
+ }
369
+
339
370
  export function deriveKeepRecentTokens(
340
371
  contextWindow: number,
341
372
  keepRecentPercent: number,
package/src/constants.ts CHANGED
@@ -56,7 +56,7 @@ export const ALLOWED_STATUSES = [
56
56
  "failed",
57
57
  ] as const;
58
58
 
59
- export const DEFAULT_TRIGGER_AT_PERCENT = 75;
59
+ export const DEFAULT_TRIGGER_AT_PERCENT = 70;
60
60
  export const DEFAULT_KEEP_RECENT_PERCENT = 20;
61
61
  export const DEFAULT_ARTIFACT_DIRECTORY = "session-continuity";
62
62
  export const DEFAULT_SYNTHESIS_MODEL = "inherit";