pi-usereq 0.47.0 → 0.49.0

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,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.49.0](https://github.com/Ogekuri/PI-useReq/compare/v0.48.0..v0.49.0) - 2026-07-13
4
+ ### 🚜 Changes
5
+ - Reorder command summary: Configuration before User's Request [useReq] *(prompts)*
6
+ - Move the User's Request line after the Configuration block in the bundled prompt-backed command invocation summary so sections render as Command, Configuration, then User's Request, each separated by one blank line. Add REQ-353 and TST-131, update renderPromptCommandSummary in src/core/prompts.ts, and regenerate REFERENCES.md.
7
+
8
+ ## [0.48.0](https://github.com/Ogekuri/PI-useReq/compare/v0.47.0..v0.48.0) - 2026-07-13
9
+ ### 🐛 Bug Fixes
10
+ - approve scripts at correct install root [useReq] *(install-static-checkers)*
11
+ - getConsumerInstallRoot preferred INIT_CWD over npm_config_local_prefix.
12
+ - pi runs 'npm install --prefix <root>' from its own cwd, so INIT_CWD is the
13
+ - caller cwd, not the install root; the allowScripts approval was written to
14
+ - the wrong project (or nowhere) and 'npm warn allow-scripts' persisted on
15
+ - every 'pi update --extensions'.
16
+ - Swap priority to prefer npm_config_local_prefix (the real install root in
17
+ - both --prefix and plain installs), falling back to INIT_CWD.
18
+ - Add reproducer unit test; update WORKFLOW.md call-trace description.
19
+ - Satisfies DES-020, REQ-352.
20
+
3
21
  ## [0.47.0](https://github.com/Ogekuri/PI-useReq/compare/v0.46.0..v0.47.0) - 2026-07-13
4
22
  ### 🐛 Bug Fixes
5
23
  - Fix packages file.
@@ -636,6 +654,8 @@
636
654
  - \[0.45.0\]: https://github.com/Ogekuri/PI-useReq/releases/tag/v0.45.0
637
655
  - \[0.46.0\]: https://github.com/Ogekuri/PI-useReq/releases/tag/v0.46.0
638
656
  - \[0.47.0\]: https://github.com/Ogekuri/PI-useReq/releases/tag/v0.47.0
657
+ - \[0.48.0\]: https://github.com/Ogekuri/PI-useReq/releases/tag/v0.48.0
658
+ - \[0.49.0\]: https://github.com/Ogekuri/PI-useReq/releases/tag/v0.49.0
639
659
 
640
660
  [0.1.0]: https://github.com/Ogekuri/PI-useReq/releases/tag/v0.1.0
641
661
  [0.2.0]: https://github.com/Ogekuri/PI-useReq/compare/v0.1.0..v0.2.0
@@ -682,3 +702,5 @@
682
702
  [0.45.0]: https://github.com/Ogekuri/PI-useReq/compare/v0.44.0..v0.45.0
683
703
  [0.46.0]: https://github.com/Ogekuri/PI-useReq/compare/v0.45.0..v0.46.0
684
704
  [0.47.0]: https://github.com/Ogekuri/PI-useReq/compare/v0.46.0..v0.47.0
705
+ [0.48.0]: https://github.com/Ogekuri/PI-useReq/compare/v0.47.0..v0.48.0
706
+ [0.49.0]: https://github.com/Ogekuri/PI-useReq/compare/v0.48.0..v0.49.0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # PI-useReq/pi-usereq (0.47.0)
1
+ # PI-useReq/pi-usereq (0.49.0)
2
2
 
3
3
  <p align="center">
4
4
  <img src="https://img.shields.io/badge/python-3.11%2B-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python 3.11+">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-usereq",
3
- "version": "0.47.0",
3
+ "version": "0.49.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Ogekuri/PI-useReq.git"
@@ -3444,12 +3444,12 @@ import { readBundledInstruction, readBundledPrompt } from "./resources.js";
3444
3444
 
3445
3445
  ### fn `export function renderPromptCommandSummary(` (L385-425)
3446
3446
  - @brief Builds the on-screen command invocation summary for one bundled prompt-backed `req-<prompt>` command.
3447
- - @details Renders the command name without the `req-` prefix in uppercase, the user request arguments, and the active configuration fields (`docs-dir`, `src-dir`, `tests-dir`, enabled context files, `AUTO_GIT_COMMIT`, effective `GIT_WORKTREE_ENABLED`, `GIT_WORKTREE_PREFIX`, enabled static-check languages, and `enabled-tools`) so the TUI shows only a compact summary while the full rendered prompt is delivered hidden to the LLM agent. Static-check languages are emitted in canonical `DEFAULT_STATIC_CHECK_LANGUAGES` order; enabled tools are emitted in documented menu order via `comparePiUsereqStartupToolNames`. The `context files`, `static code checks`, and `enabled tools` fields render the literal `none` placeholder whenever their respective enabled-item list is empty so the summary never shows a blank value. Runtime is O(l + t log t) where l is language count and t is enabled-tool count. No external state is mutated.
3447
+ - @details Renders the command name without the `req-` prefix in uppercase, the user request arguments, and the active configuration fields (`docs-dir`, `src-dir`, `tests-dir`, enabled context files, `AUTO_GIT_COMMIT`, effective `GIT_WORKTREE_ENABLED`, `GIT_WORKTREE_PREFIX`, enabled static-check languages, and `enabled-tools`) so the TUI shows only a compact summary while the full rendered prompt is delivered hidden to the LLM agent. Static-check languages are emitted in canonical `DEFAULT_STATIC_CHECK_LANGUAGES` order; enabled tools are emitted in documented menu order via `comparePiUsereqStartupToolNames`. The `context files`, `static code checks`, and `enabled tools` fields render the literal `none` placeholder whenever their respective enabled-item list is empty so the summary never shows a blank value. Sections are emitted in the order `Command:`, `Configuration:` with its bullet list, then `User's Request:`, each separated by one blank line. Runtime is O(l + t log t) where l is language count and t is enabled-tool count. No external state is mutated.
3448
3448
  - @param[in] promptName {string} Bundled prompt name without the `req-` prefix.
3449
3449
  - @param[in] args {string} User request arguments passed to the slash command.
3450
3450
  - @param[in] config {UseReqConfig} Effective project configuration supplying directory, git, static-check, and tool fields.
3451
3451
  - @return {string} Multi-line command invocation summary text.
3452
- - @satisfies REQ-335, REQ-336, REQ-337, REQ-338
3452
+ - @satisfies REQ-335, REQ-336, REQ-337, REQ-338, REQ-353
3453
3453
 
3454
3454
  ## Symbol Index
3455
3455
  |Symbol|Kind|Vis|Lines|Sig|
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "PI-useReq Requirements"
3
3
  description: Software requirements specification
4
- version: "0.0.77"
4
+ version: "0.0.78"
5
5
  date: "2026-07-13"
6
6
  author: "OpenAI Codex"
7
7
  scope:
@@ -168,6 +168,7 @@ PI-useReq is a TypeScript pi extension plus companion Node CLI and standalone ex
168
168
  - **REQ-336**: MUST render the command invocation summary with the command name without the `req-` prefix in uppercase and the user request arguments.
169
169
  - **REQ-337**: MUST include `docs-dir`, `src-dir`, `tests-dir`, enabled context files, `AUTO_GIT_COMMIT`, effective `GIT_WORKTREE_ENABLED`, `GIT_WORKTREE_PREFIX`, enabled static-check languages, and `enabled-tools` in the command invocation summary.
170
170
  - **REQ-338**: MUST render `none` for the command invocation summary `context files`, `static code checks`, and `enabled tools` fields whenever their respective enabled-item list is empty.
171
+ - **REQ-353**: MUST render the command invocation summary sections in the order `Command:`, `Configuration:` with its bullet list, then `User's Request:`, separated by one blank line between consecutive sections.
171
172
  - **REQ-008**: MUST provide a `Language static code checkers` submenu that adds, views, confirms-before-removes, and resets global Command checker entries, plus toggles local per-language enablement.
172
173
  - **REQ-160**: MUST hardcode `Command` as the only user-configurable static-check module and omit module-selection UI from static-check configuration menus.
173
174
  - **REQ-161**: MUST hide `Dummy` from user-configurable static-check menus while preserving existing-config parsing and debug-driver support for `Dummy` entries.
@@ -543,6 +544,7 @@ PI-useReq is a TypeScript pi extension plus companion Node CLI and standalone ex
543
544
  - **TST-119**: MUST verify `%%CONTEXT_FILES%%` replacement emits one section per enabled existing file in the documented order and omits disabled or missing files.
544
545
  - **TST-120**: MUST verify `%%CONTEXT_FILES%%` sections use the file-name heading, the pre-substituted HTML file reference, and four-backtick `markdown` fences around raw content.
545
546
  - **TST-122**: MUST verify the command invocation summary renders `none` for `context files`, `static code checks`, and `enabled tools` when no items are enabled in each respective category.
547
+ - **TST-131**: MUST verify the command invocation summary renders sections in the order `Command:`, `Configuration:`, then `User's Request:`, with one blank line between consecutive sections.
546
548
  - **TST-123**: MUST verify `resolveCheckerExecutable` probes bundled `node_modules/.bin` paths before `PATH` scan.
547
549
  - **TST-124**: MUST verify `scripts/install-static-checkers.ts` always returns exit code `0` regardless of probe or install outcomes.
548
550
  - **TST-125**: MUST verify `session_start` emits one warning notification for missing enabled checkers without aborting or transitioning workflow state.
@@ -1309,7 +1309,7 @@
1309
1309
  - Internal Call-Trace Tree:
1310
1310
  - `main(...)`: when invoked as the npm `postinstall` lifecycle, best-effort write consumer-root name-only `allowScripts` approvals, then probe each bundled npm checker, attempt best-effort install on miss, print native-checker guidance, and return `0` [`scripts/install-static-checkers.ts`]
1311
1311
  - `approvePendingInstallScripts(...)`: best-effort write name-only `allowScripts` approvals into the consumer-root `package.json` for installed packages declaring install lifecycle scripts before probing [`scripts/install-static-checkers.ts`]
1312
- - `getConsumerInstallRoot(...)`: resolve the consumer install root from the npm `INIT_CWD` or `npm_config_local_prefix` lifecycle environment [`scripts/install-static-checkers.ts`]
1312
+ - `getConsumerInstallRoot(...)`: resolve the consumer install root preferring the npm `npm_config_local_prefix` install root (correct under pi `npm install --prefix <root>` flows) over the `INIT_CWD` caller-cwd fallback [`scripts/install-static-checkers.ts`]
1313
1313
  - `collectNodeModulesPackages(...)`: scan consumer-root `node_modules` and parse each readable package manifest [`scripts/install-static-checkers.ts`]
1314
1314
  - `selectInstallScriptPackageNames(...)`: select package names declaring `preinstall`, `install`, or `postinstall` scripts [`scripts/install-static-checkers.ts`]
1315
1315
  - `mergeAllowScriptsEntries(...)`: merge name-only approvals into the existing `allowScripts` map while preserving prior entries and explicit denials [`scripts/install-static-checkers.ts`]
@@ -71,12 +71,13 @@ export interface InstallScriptApprovalDeps {
71
71
 
72
72
  /**
73
73
  * @brief Resolves the consumer install root that owns the active npm install transaction.
74
- * @details During an npm lifecycle script npm sets `INIT_CWD` to the invocation directory and `npm_config_local_prefix` to the resolved project prefix; both point at the true consumer root instead of the installed package directory that is the postinstall `process.cwd()`. Returns the first available value so the approval flow writes the consumer-root `package.json` allowScripts map instead of the nested `node_modules/<pkg>` directory. Runtime is O(1). No external state is mutated.
74
+ * @details During an npm lifecycle script npm sets `npm_config_local_prefix` to the resolved project prefix (the directory holding the `package.json` npm operates on) and `INIT_CWD` to the npm invocation directory. The pi extension host drives installs with `npm install <pkg> --prefix <installRoot>` from its own caller cwd, so in that flow `INIT_CWD` is the host caller cwd, NOT the install root, while `npm_config_local_prefix` equals the install root in both `--prefix` and plain `cd <root> && npm install` flows. Therefore `npm_config_local_prefix` MUST be selected first; `INIT_CWD` is retained only as a fallback for npm versions or flows that leave the prefix unset. Selecting `INIT_CWD` first would resolve the caller project (or a nonexistent path), so the `allowScripts` approval would be written to the wrong `package.json` (or nowhere) and the `npm warn allow-scripts` warning would persist on every extension update. Runtime is O(1). No external state is mutated.
75
75
  * @param[in] env {NodeJS.ProcessEnv} Environment map read for npm lifecycle path variables.
76
- * @return {string | undefined} Consumer install root, or `undefined` when not running inside an npm lifecycle.
76
+ * @return {string | undefined} Consumer install root, preferring `npm_config_local_prefix` then `INIT_CWD`, or `undefined` when not running inside an npm lifecycle.
77
+ * @satisfies DES-020, REQ-352
77
78
  */
78
79
  export function getConsumerInstallRoot(env: NodeJS.ProcessEnv = process.env): string | undefined {
79
- return env.INIT_CWD || env.npm_config_local_prefix || undefined;
80
+ return env.npm_config_local_prefix || env.INIT_CWD || undefined;
80
81
  }
81
82
 
82
83
  /**
@@ -375,12 +375,12 @@ export const PROMPT_COMMAND_SUMMARY_CUSTOM_TYPE = "pi-usereq-prompt-command";
375
375
 
376
376
  /**
377
377
  * @brief Builds the on-screen command invocation summary for one bundled prompt-backed `req-<prompt>` command.
378
- * @details Renders the command name without the `req-` prefix in uppercase, the user request arguments, and the active configuration fields (`docs-dir`, `src-dir`, `tests-dir`, enabled context files, `AUTO_GIT_COMMIT`, effective `GIT_WORKTREE_ENABLED`, `GIT_WORKTREE_PREFIX`, enabled static-check languages, and `enabled-tools`) so the TUI shows only a compact summary while the full rendered prompt is delivered hidden to the LLM agent. Static-check languages are emitted in canonical `DEFAULT_STATIC_CHECK_LANGUAGES` order; enabled tools are emitted in documented menu order via `comparePiUsereqStartupToolNames`. The `context files`, `static code checks`, and `enabled tools` fields render the literal `none` placeholder whenever their respective enabled-item list is empty so the summary never shows a blank value. Runtime is O(l + t log t) where l is language count and t is enabled-tool count. No external state is mutated.
378
+ * @details Renders the command name without the `req-` prefix in uppercase, the user request arguments, and the active configuration fields (`docs-dir`, `src-dir`, `tests-dir`, enabled context files, `AUTO_GIT_COMMIT`, effective `GIT_WORKTREE_ENABLED`, `GIT_WORKTREE_PREFIX`, enabled static-check languages, and `enabled-tools`) so the TUI shows only a compact summary while the full rendered prompt is delivered hidden to the LLM agent. Static-check languages are emitted in canonical `DEFAULT_STATIC_CHECK_LANGUAGES` order; enabled tools are emitted in documented menu order via `comparePiUsereqStartupToolNames`. The `context files`, `static code checks`, and `enabled tools` fields render the literal `none` placeholder whenever their respective enabled-item list is empty so the summary never shows a blank value. Sections are emitted in the order `Command:`, `Configuration:` with its bullet list, then `User's Request:`, each separated by one blank line. Runtime is O(l + t log t) where l is language count and t is enabled-tool count. No external state is mutated.
379
379
  * @param[in] promptName {string} Bundled prompt name without the `req-` prefix.
380
380
  * @param[in] args {string} User request arguments passed to the slash command.
381
381
  * @param[in] config {UseReqConfig} Effective project configuration supplying directory, git, static-check, and tool fields.
382
382
  * @return {string} Multi-line command invocation summary text.
383
- * @satisfies REQ-335, REQ-336, REQ-337, REQ-338
383
+ * @satisfies REQ-335, REQ-336, REQ-337, REQ-338, REQ-353
384
384
  */
385
385
  export function renderPromptCommandSummary(
386
386
  promptName: string,
@@ -408,8 +408,6 @@ export function renderPromptCommandSummary(
408
408
  const lines: string[] = [
409
409
  `Command: ${promptName.toUpperCase()}`,
410
410
  "",
411
- `User's Request: ${args}`,
412
- "",
413
411
  "Configuration:",
414
412
  `- document dir: ${config["docs-dir"]}`,
415
413
  `- source-code dirs: ${config["src-dir"].join(", ")}`,
@@ -420,6 +418,8 @@ export function renderPromptCommandSummary(
420
418
  `- worktree prefix: ${config.GIT_WORKTREE_PREFIX}`,
421
419
  `- static code checks: ${enabledLanguages}`,
422
420
  `- enabled tools: ${enabledTools}`,
421
+ "",
422
+ `User's Request: ${args}`,
423
423
  ];
424
424
  return lines.join("\n");
425
425
  }
@@ -153,6 +153,32 @@ test("getConsumerInstallRoot falls back to npm_config_local_prefix and then unde
153
153
  }
154
154
  });
155
155
 
156
+ test("getConsumerInstallRoot prefers npm_config_local_prefix over INIT_CWD for --prefix installs", () => {
157
+ // Reproducer for `pi update --extensions` `npm warn allow-scripts`: the pi host runs
158
+ // `npm install <pkg> --prefix <installRoot>` from its own caller cwd, so INIT_CWD is the
159
+ // caller cwd while npm_config_local_prefix is the real install root. Resolving INIT_CWD
160
+ // first writes the allowScripts approval to the wrong project (or nowhere) and the warning
161
+ // persists on every extension update.
162
+ const previousInitCwd = process.env.INIT_CWD;
163
+ const previousPrefix = process.env.npm_config_local_prefix;
164
+ try {
165
+ process.env.INIT_CWD = "/tmp/pi-usereq-caller-cwd";
166
+ process.env.npm_config_local_prefix = "/tmp/pi-usereq-install-root";
167
+ assert.equal(getConsumerInstallRoot(), "/tmp/pi-usereq-install-root");
168
+ } finally {
169
+ if (previousInitCwd === undefined) {
170
+ delete process.env.INIT_CWD;
171
+ } else {
172
+ process.env.INIT_CWD = previousInitCwd;
173
+ }
174
+ if (previousPrefix === undefined) {
175
+ delete process.env.npm_config_local_prefix;
176
+ } else {
177
+ process.env.npm_config_local_prefix = previousPrefix;
178
+ }
179
+ }
180
+ });
181
+
156
182
  test("selectInstallScriptPackageNames returns only packages with lifecycle scripts", () => {
157
183
  const packages: NodeModulesPackage[] = [
158
184
  { name: "has-postinstall", scripts: { postinstall: "node install.js" } },