@selesai/code 0.8.1 → 0.8.2

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
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to `@selesai/code` will be documented in this file.
4
4
 
5
+ ## [0.8.2] - 2026-08-11
6
+
7
+ ### Fixed
8
+ - **Guide version-marking no longer locks in the implicit mode.** When the recurring guide marks a new version as seen, Selesai no longer writes the fallback `compact` mode into `settings.json` as if it were a user choice. An explicit `full`, `compact`, or `off` mode is still preserved across version-only writes, so the guide keeps following the current default until you choose otherwise.
9
+
5
10
  ## [0.8.1] - 2026-08-11
6
11
 
7
12
  ### Fixed
@@ -3,6 +3,7 @@
3
3
  ## [Unreleased]
4
4
 
5
5
  ### Fixed
6
+ - **Guide version-marking never persists an implicit mode** — `markGuideVersionSeen` (version-only writes) preserves an explicit user mode but never writes the fallback default as a user choice, so the guide keeps following the current default instead of locking in `compact`.
6
7
  - **Guide defaults to compact mode** — When `selesaiGuide.mode` is unset, the recurring guide opens in compact mode instead of the full tour. Explicit `full`, `compact`, or `off` settings are still honored.
7
8
 
8
9
  ### Changed
@@ -200,9 +200,17 @@ export function saveGuidePreferences(
200
200
  if (!settings) return false;
201
201
 
202
202
  const current = getGuidePreferences(settings);
203
- const next: Record<string, unknown> = {
204
- mode: update.mode ?? current.mode,
205
- };
203
+ const raw = isRecord(settings) && isRecord(settings.selesaiGuide)
204
+ ? settings.selesaiGuide
205
+ : {};
206
+ const next: Record<string, unknown> = {};
207
+ if (update.mode !== undefined) {
208
+ next.mode = update.mode;
209
+ } else if (typeof raw.mode === "string") {
210
+ // Version-only writes (markGuideVersionSeen) must preserve an explicit user
211
+ // mode but never persist the fallback default as a user choice.
212
+ next.mode = raw.mode;
213
+ }
206
214
  const lastSeenVersion = update.lastSeenVersion === null
207
215
  ? undefined
208
216
  : update.lastSeenVersion ?? current.lastSeenVersion;
@@ -10,6 +10,7 @@ import {
10
10
  getGuideFeatureLines,
11
11
  getGuidePreferences,
12
12
  getNewGuideFeatures,
13
+ markGuideVersionSeen,
13
14
  resolveGuideDisplayMode,
14
15
  saveGuidePreferences,
15
16
  type GuideFeature,
@@ -99,6 +100,28 @@ test("guide dismissal persists only the mode and version marker", () => {
99
100
  }
100
101
  });
101
102
 
103
+ test("version marking never persists an implicit guide mode", () => {
104
+ const dir = mkdtempSync(join(tmpdir(), "selesai-guide-"));
105
+ const settingsPath = join(dir, "settings.json");
106
+
107
+ try {
108
+ // markGuideVersionSeen writes only the version marker; the mode stays
109
+ // unset so the default (compact) applies instead of being locked in.
110
+ assert.equal(markGuideVersionSeen("0.5.3", settingsPath), true);
111
+ const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as Record<string, unknown>;
112
+ assert.deepEqual(settings.selesaiGuide, { lastSeenVersion: "0.5.3" });
113
+ assert.equal(getGuidePreferences(settings).mode, "compact");
114
+
115
+ // An explicitly chosen mode is preserved across version-only writes.
116
+ assert.equal(saveGuidePreferences({ mode: "off" }, settingsPath), true);
117
+ assert.equal(saveGuidePreferences({ lastSeenVersion: "0.6.0" }, settingsPath), true);
118
+ const after = JSON.parse(readFileSync(settingsPath, "utf8")) as Record<string, unknown>;
119
+ assert.deepEqual(after.selesaiGuide, { mode: "off", lastSeenVersion: "0.6.0" });
120
+ } finally {
121
+ rmSync(dir, { recursive: true, force: true });
122
+ }
123
+ });
124
+
102
125
  test("invalid persisted guide settings fall back to the compact guide", () => {
103
126
  assert.deepEqual(getGuidePreferences({ selesaiGuide: { mode: "unexpected", lastSeenVersion: 42 } }), {
104
127
  mode: "compact",
@@ -20,7 +20,7 @@
20
20
  "@earendil-works/pi-agent-core": "0.81.0",
21
21
  "@earendil-works/pi-ai": "0.81.0",
22
22
  "@earendil-works/pi-tui": "0.81.0",
23
- "@selesai/code": "0.8.1",
23
+ "@selesai/code": "0.8.2",
24
24
  "@types/node": "24.13.3",
25
25
  "typescript": "5.9.3"
26
26
  },
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "../../..": {
49
49
  "name": "@selesai/code",
50
- "version": "0.8.1",
50
+ "version": "0.8.2",
51
51
  "dev": true,
52
52
  "dependencies": {
53
53
  "@earendil-works/pi-agent-core": "0.83.0",
@@ -97,7 +97,7 @@
97
97
  "devDependencies": {
98
98
  "@earendil-works/pi-agent-core": "0.81.0",
99
99
  "@earendil-works/pi-ai": "0.81.0",
100
- "@selesai/code": "0.8.1",
100
+ "@selesai/code": "0.8.2",
101
101
  "@earendil-works/pi-tui": "0.81.0",
102
102
  "@types/node": "24.13.3",
103
103
  "typescript": "5.9.3"
@@ -26,7 +26,7 @@ const expectedHostPeerRanges = {
26
26
  const expectedHostDevVersions = {
27
27
  "@earendil-works/pi-agent-core": "0.81.0",
28
28
  "@earendil-works/pi-ai": "0.81.0",
29
- "@selesai/code": "0.8.1",
29
+ "@selesai/code": "0.8.2",
30
30
  "@earendil-works/pi-tui": "0.81.0",
31
31
  } satisfies Record<(typeof hostPeerPackages)[number], string>;
32
32
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selesai/code",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "Maintained, extension-first Pi coding agent with built-in workflows, subagents, web research, questions, skills, and an enhanced terminal UI.",
5
5
  "type": "module",
6
6
  "repository": {