@signalridge/pi-welcome 1.3.4 → 1.3.6

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,59 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.3.6
4
+ ### Patch Changes
5
+
6
+ - d9219d4: Correct shipped documentation that contradicted the code or the manifest.
7
+
8
+ - `pi-subagents`: the summary line still advertised protocol-v3 spawning while
9
+ the feature list and the managed-spawn section described v4.
10
+ - `pi-worktree`: the workspace-switching section named `/tree`; the registered
11
+ command is `/worktree`.
12
+ - `pi-workflows`: removed an orphaned sentence fragment left behind by an edit
13
+ to the saved-workflow paragraph.
14
+ - `pi-plan-mode`, `pi-goal`, `pi-usage-extension`: the stated Pi floor
15
+ (`0.80.6`, `0.42.4+`) contradicted the declared `^0.84.0` peer range, which
16
+ resolves to `0.84.x`. `pi-usage-extension` also carried a "Last updated"
17
+ stamp from a version that predates the workspace baseline.
18
+ - `pi-welcome`: the example card was a real session capture. It is now a
19
+ generic sample, and Install moved above the configuration sections instead of
20
+ sitting below them.
21
+ - 1f586f8: Expand Pi peer support to `^0.84.0 || ^0.85.0`, retaining 0.84 compatibility while admitting 0.85 releases. The previous zero-major caret range excluded Pi 0.85.1. Update existing Pi development dependency pins to 0.85.1.
22
+
23
+ ## 1.3.5
24
+ ### Patch Changes
25
+
26
+ - c1b1741: Durability and containment fixes found in a repository-wide scan.
27
+
28
+ `pi-gpt-fast` rewrote pi's own global `settings.json` with a plain
29
+ `writeFileSync`. That file is shared with pi and every other extension, and this
30
+ one is the only writer of it; a torn write would have left the user with no pi
31
+ configuration at all rather than just no gpt-fast setting. It now writes a temp
32
+ file and renames, matching every other settings writer in the repository.
33
+ `pi-goal` gets the same treatment for its cross-project goal state file, which
34
+ its own settings module already did.
35
+
36
+ `pi-ralph-wiggum` resolved `/ralph start <path>` straight against the session
37
+ cwd, so `../../notes.md` would create directories and a file outside the project
38
+ the user opened — silently, before the loop started. This extension drives long
39
+ unattended loops, so that command is as likely to come from a model as from a
40
+ person. Task-file paths are now required to stay inside the workspace, on the
41
+ command, on the `ralph_start` tool, and on the paths read back out of persisted
42
+ state, so a state file written earlier or edited by hand cannot pull a file in
43
+ from outside either.
44
+
45
+ The containment test canonicalizes both sides before comparing, because a purely
46
+ lexical one is defeated by a symlink: every segment of `linked/plan.md` reads as
47
+ inside the workspace when `linked` is a door out of it. `realpathSync` throws on
48
+ a path that does not exist yet — the ordinary case, since `start` is usually
49
+ creating the file — so it resolves the deepest existing ancestor and re-attaches
50
+ the not-yet-created suffix, which cannot itself be a link. The traversal test
51
+ matches a `..` segment rather than a `..` prefix; the prefix form also rejected
52
+ `..notes.md`, an ordinary filename sitting in the workspace.
53
+
54
+ Every remaining bare `catch {}` now says why the error is safe to drop, matching
55
+ the convention the rest of the repository already follows.
56
+
3
57
  ## 1.3.4
4
58
  ### Patch Changes
5
59
 
package/README.md CHANGED
@@ -10,18 +10,18 @@ redraws it, and collapses to a width-safe compact summary on narrow terminals.
10
10
  │ │
11
11
  │ Ctrl+C interrupt · / commands · ! bash · Ctrl+L clear │
12
12
  │ │
13
- │ Directory: ~/ghq/github.com/signalridge/pi-extensions │
13
+ │ Directory: ~/code/acme-api │
14
14
  │ Branch: main [+392 -202] │
15
15
  │ Session: (new) │
16
16
  │ Model: openai-codex / gpt-5.6-luna · thinking max │
17
17
  │ Budget: 400K · compacts at 270K │
18
- │ Version: 0.84.1 │
18
+ │ Version: 0.85.1 │
19
19
  │ │
20
20
  │ Context: AGENTS.md │
21
- │ Skills: commit, dev-preferences, toolbelt, write-tui +12 │
22
- │ Prompts: /plan, /review, /ship +4 │
21
+ │ Skills: commit, release, review +12 │
22
+ │ Prompts: /plan, /ship +4 │
23
23
  │ Extensions: btw, code-actions, goal, gpt-fast, statusline +18 │
24
- │ Themes: catppuccin-mocha, signalridge-ridgeline +2 │
24
+ │ Themes: catppuccin-mocha +2 │
25
25
  │ Tools: 18 active of 42 │
26
26
  │ │
27
27
  ╰─────────────────────────────────────────────────────────────────────────╯
@@ -30,6 +30,22 @@ redraws it, and collapses to a width-safe compact summary on narrow terminals.
30
30
  No logo and no wordmark: the card exists to say what this session is, and a
31
31
  brand line says nothing a returning user does not already know.
32
32
 
33
+ ## Install
34
+
35
+ Supports Pi `0.84.x` and `0.85.x`; tested with `0.85.1` — see the `peerDependencies` range.
36
+
37
+ ```bash
38
+ pi install npm:@signalridge/pi-welcome
39
+ ```
40
+
41
+ ## Use from this checkout
42
+
43
+ From the repository root:
44
+
45
+ ```bash
46
+ pi -e ./packages/pi-welcome
47
+ ```
48
+
33
49
  ## Turn on `quietStartup`
34
50
 
35
51
  The card is designed to be the whole opening screen. Pi's own startup is a
@@ -75,17 +91,3 @@ attacker-controlled in a cloned repository, and the card is a persisted entry
75
91
  replayed on every resume. Control characters and bidirectional overrides are
76
92
  neutralized at render time, so an entry stored before that landed is cleaned up
77
93
  on the way out too.
78
-
79
- ## Install
80
-
81
- ```bash
82
- pi install npm:@signalridge/pi-welcome
83
- ```
84
-
85
- ## Use from this checkout
86
-
87
- From the repository root:
88
-
89
- ```bash
90
- pi -e ./packages/pi-welcome
91
- ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalridge/pi-welcome",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "Startup resource and repository summary card for Pi.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,8 +9,8 @@
9
9
  "lifecycle": "stable"
10
10
  },
11
11
  "peerDependencies": {
12
- "@earendil-works/pi-coding-agent": "^0.84.0",
13
- "@earendil-works/pi-tui": "^0.84.0"
12
+ "@earendil-works/pi-coding-agent": "^0.84.0 || ^0.85.0",
13
+ "@earendil-works/pi-tui": "^0.84.0 || ^0.85.0"
14
14
  },
15
15
  "pi": {
16
16
  "extensions": [
package/src/index.ts CHANGED
@@ -221,14 +221,19 @@ function collectExtensionNames(cwd: string): string[] {
221
221
  const bare = (spec.startsWith("@") ? (spec.split("/")[1] ?? spec) : basename(spec)).replace(/@.*$/u, "");
222
222
  names.push(bare.replace(/^pi-/u, ""));
223
223
  }
224
- } catch {}
224
+ } catch {
225
+ // Discovery is best-effort: a malformed manifest contributes no names
226
+ // rather than blanking the whole card.
227
+ }
225
228
  }
226
229
  for (const directory of [join(getAgentDir(), "extensions"), join(cwd, ".pi", "extensions")]) {
227
230
  try {
228
231
  for (const entry of readdirSync(directory)) {
229
232
  names.push(entry.replace(/\.[cm]?[jt]s$/u, "").replace(/^pi-/u, ""));
230
233
  }
231
- } catch {}
234
+ } catch {
235
+ // An extensions directory that does not exist is the normal case.
236
+ }
232
237
  }
233
238
  return tidy(names);
234
239
  }
@@ -271,7 +276,9 @@ export function collectResources(pi: ExtensionAPI, cwd: string): [string, string
271
276
  // Several scopes can contribute the same filename (a project AGENTS.md and
272
277
  // a global one); the card names kinds of context, not paths.
273
278
  push("Context", nameList(tidy(files.map((file) => basename(file.path)))));
274
- } catch {}
279
+ } catch {
280
+ // One unreadable source drops its row; the card still renders the rest.
281
+ }
275
282
 
276
283
  try {
277
284
  const commands = pi.getCommands?.() ?? [];
@@ -279,7 +286,9 @@ export function collectResources(pi: ExtensionAPI, cwd: string): [string, string
279
286
  tidy(commands.filter((command) => command.source === source).map((command) => `${prefix}${command.name}`));
280
287
  push("Skills", nameList(named("skill")));
281
288
  push("Prompts", nameList(named("prompt", "/")));
282
- } catch {}
289
+ } catch {
290
+ // A host without these accessors simply contributes no rows.
291
+ }
283
292
 
284
293
  push("Extensions", nameList(collectExtensionNames(cwd)));
285
294
  push("Themes", nameList(collectThemeNames()));
@@ -288,7 +297,9 @@ export function collectResources(pi: ExtensionAPI, cwd: string): [string, string
288
297
  const all = pi.getAllTools?.() ?? [];
289
298
  const active = pi.getActiveTools?.() ?? [];
290
299
  if (all.length) push("Tools", `${active.length} active of ${all.length}`);
291
- } catch {}
300
+ } catch {
301
+ // A host without these accessors simply contributes no rows.
302
+ }
292
303
 
293
304
  return rows;
294
305
  }
@@ -501,7 +512,10 @@ export default function (pi: ExtensionAPI) {
501
512
  return;
502
513
  }
503
514
  }
504
- } catch {}
515
+ } catch {
516
+ // Unreadable entries mean we cannot prove the card was already written.
517
+ // Falling through re-appends it, which beats never showing it at all.
518
+ }
505
519
 
506
520
  try {
507
521
  pi.appendEntry<WelcomeData>(ENTRY_TYPE, collect(pi, ctx));