pi-usereq 0.10.0 → 0.12.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 +66 -0
- package/README.md +6 -6
- package/package.json +1 -1
- package/pi-usereq/docs/REFERENCES.md +861 -704
- package/pi-usereq/docs/REQUIREMENTS.md +152 -95
- package/pi-usereq/docs/WORKFLOW.md +228 -65
- package/scripts/lib/extension-debug-harness.ts +2 -2
- package/scripts/tool-args-to-params.ts +2 -2
- package/src/cli.ts +12 -12
- package/src/core/debug-runtime.ts +2 -2
- package/src/core/extension-status.ts +98 -36
- package/src/core/pi-notify.ts +5 -5
- package/src/core/pi-usereq-tools.ts +4 -2
- package/src/core/prompt-command-catalog.ts +4 -5
- package/src/core/prompt-command-runtime.ts +347 -42
- package/src/core/prompts.ts +0 -2
- package/src/core/req-references-command.ts +175 -0
- package/src/core/req-reset-command.ts +323 -0
- package/src/core/resources.ts +6 -23
- package/src/core/runtime-project-paths.ts +21 -1
- package/src/core/settings-menu.ts +85 -28
- package/src/core/tool-runner.ts +26 -6
- package/src/index.ts +530 -104
- package/tests/attended-results-scenarios.ts +5 -5
- package/tests/cli-command-option-parity.test.ts +25 -25
- package/tests/debug-extension-harness.test.ts +8 -2
- package/tests/extension-registration.test.ts +1109 -76
- package/tests/oracle-project.test.ts +4 -4
- package/tests/oracle-standalone.test.ts +5 -5
- package/src/core/reference-payload.ts +0 -752
- package/src/resources/prompts/references.md +0 -64
- /package/tests/fixtures_attended_results/project/{references.json → summarize.json} +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_c.c.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_cpp.cpp.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_csharp.cs.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_elixir.ex.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_go.go.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_haskell.hs.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_java.java.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_javascript.js.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_kotlin.kt.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_lua.lua.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_perl.pl.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_php.php.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_python.py.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_ruby.rb.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_rust.rs.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_scala.scala.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_shell.sh.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_swift.swift.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_typescript.ts.json +0 -0
- /package/tests/fixtures_attended_results/standalone/{files-references → files-summarize}/fixture_zig.zig.json +0 -0
|
@@ -211,10 +211,10 @@ const PROMPT_COMMAND_EXAMPLES: Record<string, string> = {
|
|
|
211
211
|
*/
|
|
212
212
|
const TOOL_EXAMPLES: Record<string, string> = {
|
|
213
213
|
"files-tokens": `npm run debug:ext:tool -- --name files-tokens --params '{"files":["pi-usereq/docs/REQUIREMENTS.md","pi-usereq/docs/WORKFLOW.md"]}' --cwd . --format json`,
|
|
214
|
-
"files-
|
|
214
|
+
"files-summarize": `npm run debug:ext:tool -- --name files-summarize --params '{"files":["src/index.ts","src/core/tool-runner.ts"]}' --cwd . --format pretty`,
|
|
215
215
|
"files-compress": `npm run debug:ext:tool -- --name files-compress --params '{"files":["src/index.ts"],"enableLineNumbers":true}' --cwd . --format json`,
|
|
216
216
|
"files-search": `npm run debug:ext:tool -- --name files-search --params '{"tag":"FUNCTION|METHOD","pattern":"^run","files":["src/core/tool-runner.ts"],"enableLineNumbers":true}' --cwd . --format pretty`,
|
|
217
|
-
|
|
217
|
+
summarize: "npm run debug:ext:tool -- --name summarize --cwd . --format pretty",
|
|
218
218
|
compress: `npm run debug:ext:tool -- --name compress --params '{"enableLineNumbers":true}' --cwd . --format json`,
|
|
219
219
|
search: `npm run debug:ext:tool -- --name search --params '{"tag":"FUNCTION","pattern":"^run","enableLineNumbers":true}' --cwd . --format pretty`,
|
|
220
220
|
tokens: "npm run debug:ext:tool -- --name tokens --cwd . --format json",
|
|
@@ -97,7 +97,7 @@ function takeBooleanFlag(tokens: string[], flag: string): { tokens: string[]; pr
|
|
|
97
97
|
export function buildToolParamsFromArgsText(toolName: string, argsText: string): Record<string, unknown> {
|
|
98
98
|
const tokens = shellSplit(argsText);
|
|
99
99
|
switch (toolName) {
|
|
100
|
-
case "
|
|
100
|
+
case "summarize":
|
|
101
101
|
case "tokens":
|
|
102
102
|
case "static-check":
|
|
103
103
|
if (tokens.length !== 0) {
|
|
@@ -105,7 +105,7 @@ export function buildToolParamsFromArgsText(toolName: string, argsText: string):
|
|
|
105
105
|
}
|
|
106
106
|
return {};
|
|
107
107
|
case "files-tokens":
|
|
108
|
-
case "files-
|
|
108
|
+
case "files-summarize":
|
|
109
109
|
case "files-static-check":
|
|
110
110
|
return { files: tokens };
|
|
111
111
|
case "files-compress": {
|
package/src/cli.ts
CHANGED
|
@@ -20,12 +20,12 @@ import {
|
|
|
20
20
|
runCompress,
|
|
21
21
|
runFilesCompress,
|
|
22
22
|
runFilesSearch,
|
|
23
|
-
|
|
23
|
+
runFilesSummarize,
|
|
24
24
|
runFilesStaticCheck,
|
|
25
25
|
runFilesTokens,
|
|
26
26
|
runSearch,
|
|
27
27
|
runProjectStaticCheck,
|
|
28
|
-
|
|
28
|
+
runSummarize,
|
|
29
29
|
runTokens,
|
|
30
30
|
} from "./core/tool-runner.js";
|
|
31
31
|
import {
|
|
@@ -46,10 +46,10 @@ interface ParsedArgs {
|
|
|
46
46
|
enableLineNumbers?: boolean;
|
|
47
47
|
enableStaticCheck?: string[];
|
|
48
48
|
filesTokens?: string[];
|
|
49
|
-
|
|
49
|
+
filesSummarize?: string[];
|
|
50
50
|
filesCompress?: string[];
|
|
51
51
|
filesSearch?: string[];
|
|
52
|
-
|
|
52
|
+
summarize?: boolean;
|
|
53
53
|
compress?: boolean;
|
|
54
54
|
search?: [string, string];
|
|
55
55
|
tokens?: boolean;
|
|
@@ -106,9 +106,9 @@ function parseArgs(argv: string[]): ParsedArgs {
|
|
|
106
106
|
index = next;
|
|
107
107
|
break;
|
|
108
108
|
}
|
|
109
|
-
case "--files-
|
|
109
|
+
case "--files-summarize": {
|
|
110
110
|
const [values, next] = takeUntilOption(index + 1);
|
|
111
|
-
parsed.
|
|
111
|
+
parsed.filesSummarize = values;
|
|
112
112
|
index = next;
|
|
113
113
|
break;
|
|
114
114
|
}
|
|
@@ -124,8 +124,8 @@ function parseArgs(argv: string[]): ParsedArgs {
|
|
|
124
124
|
index = next;
|
|
125
125
|
break;
|
|
126
126
|
}
|
|
127
|
-
case "--
|
|
128
|
-
parsed.
|
|
127
|
+
case "--summarize":
|
|
128
|
+
parsed.summarize = true;
|
|
129
129
|
index += 1;
|
|
130
130
|
break;
|
|
131
131
|
case "--compress":
|
|
@@ -256,12 +256,12 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
256
256
|
}
|
|
257
257
|
const args = parseArgs(argv);
|
|
258
258
|
const hereOnlyProjectCommand = !!(
|
|
259
|
-
args.
|
|
259
|
+
args.summarize || args.compress || args.tokens || args.search || args.staticCheck
|
|
260
260
|
);
|
|
261
261
|
if (hereOnlyProjectCommand) {
|
|
262
262
|
if (args.base) {
|
|
263
263
|
throw new ReqError(
|
|
264
|
-
"Error: --
|
|
264
|
+
"Error: --summarize, --compress, --tokens, --find, and --static-check do not allow --base; use --here.",
|
|
265
265
|
1,
|
|
266
266
|
);
|
|
267
267
|
}
|
|
@@ -281,12 +281,12 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
if (args.filesTokens) return writeResult(runFilesTokens(args.filesTokens));
|
|
284
|
-
if (args.
|
|
284
|
+
if (args.filesSummarize) return writeResult(runFilesSummarize(args.filesSummarize, process.cwd(), args.verbose));
|
|
285
285
|
if (args.filesCompress) return writeResult(runFilesCompress(args.filesCompress, process.cwd(), args.enableLineNumbers, args.verbose));
|
|
286
286
|
if (args.filesSearch) return writeResult(runFilesSearch(args.filesSearch, args.enableLineNumbers, args.verbose));
|
|
287
287
|
if (args.testStaticCheck) return runStaticCheck(args.testStaticCheck);
|
|
288
288
|
if (args.filesStaticCheck) return writeResult(runFilesStaticCheck(args.filesStaticCheck, projectBase, config));
|
|
289
|
-
if (args.
|
|
289
|
+
if (args.summarize) return writeResult(runSummarize(projectBase, config, args.verbose));
|
|
290
290
|
if (args.compress) return writeResult(runCompress(projectBase, config, args.enableLineNumbers, args.verbose));
|
|
291
291
|
if (args.search) return writeResult(runSearch(projectBase, args.search[0], args.search[1], config, args.enableLineNumbers, args.verbose));
|
|
292
292
|
if (args.tokens) return writeResult(runTokens(projectBase, config));
|
|
@@ -26,10 +26,10 @@ export const DEFAULT_DEBUG_ENABLED = "disable" as const;
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* @brief Defines the default debug log file value.
|
|
29
|
-
* @details
|
|
29
|
+
* @details New configurations write debug JSON entries to `/tmp/PI-useReq.json` unless the user overrides the path. Access complexity is O(1).
|
|
30
30
|
* @satisfies CTN-013, REQ-237
|
|
31
31
|
*/
|
|
32
|
-
export const DEFAULT_DEBUG_LOG_FILE = "
|
|
32
|
+
export const DEFAULT_DEBUG_LOG_FILE = "/tmp/PI-useReq.json";
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* @brief Defines the default workflow-transition logging mode.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file
|
|
3
3
|
* @brief Tracks pi-usereq extension status state and renders status-bar telemetry.
|
|
4
|
-
* @details Centralizes hook interception, context-usage snapshots, run timing,
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* rendering. Side effects are limited to in-memory state mutation and interval
|
|
4
|
+
* @details Centralizes hook interception, context-usage snapshots, active-branch lookup, run timing, and deterministic status-bar formatting for the pi-usereq extension. Runtime
|
|
5
|
+
* is O(1) per event plus interval-driven re-renders while a prompt remains
|
|
6
|
+
* active. Side effects are limited to in-memory state mutation and interval
|
|
8
7
|
* scheduling through exported controller helpers.
|
|
9
8
|
*/
|
|
10
9
|
|
|
@@ -15,15 +14,13 @@ import type {
|
|
|
15
14
|
ThemeColor,
|
|
16
15
|
} from "@mariozechner/pi-coding-agent";
|
|
17
16
|
import type { UseReqConfig } from "./config.js";
|
|
17
|
+
import type { PiNotifySoundLevel } from "./pi-notify.js";
|
|
18
18
|
import type { PromptCommandExecutionPlan } from "./prompt-command-runtime.js";
|
|
19
|
-
import {
|
|
20
|
-
formatRuntimePathForDisplay,
|
|
21
|
-
getRuntimeContextPath,
|
|
22
|
-
} from "./path-context.js";
|
|
23
19
|
import {
|
|
24
20
|
restorePersistedPromptCommandRuntimeStateForSession,
|
|
25
21
|
writePersistedPromptCommandRuntimeState,
|
|
26
22
|
} from "./prompt-command-state.js";
|
|
23
|
+
import { resolveRuntimeGitBranchName } from "./runtime-project-paths.js";
|
|
27
24
|
|
|
28
25
|
/**
|
|
29
26
|
* @brief Enumerates the CLI-supported theme tokens consumed by status rendering.
|
|
@@ -115,7 +112,7 @@ export type PiUsereqWorkflowState = "idle" | "checking" | "running" | "merging"
|
|
|
115
112
|
|
|
116
113
|
/**
|
|
117
114
|
* @brief Stores the mutable runtime facts displayed by the status bar.
|
|
118
|
-
* @details Persists the prompt-orchestration workflow state, the latest context-usage snapshot, the active run start timestamp, the most recent normally completed run duration, the accumulated duration of all normally completed runs, and prompt-request metadata carried from command dispatch into the next runtime execution. Runtime state is mutated in-place by controller helpers. Compile-time only and introduces no runtime cost.
|
|
115
|
+
* @details Persists the prompt-orchestration workflow state, the latest context-usage snapshot, the active run start timestamp, the most recent normally completed run duration, the accumulated duration of all normally completed runs, the in-memory runtime sound level, and prompt-request metadata carried from command dispatch into the next runtime execution. Runtime state is mutated in-place by controller helpers. Compile-time only and introduces no runtime cost.
|
|
119
116
|
*/
|
|
120
117
|
export interface PiUsereqStatusState {
|
|
121
118
|
workflowState: PiUsereqWorkflowState;
|
|
@@ -123,6 +120,7 @@ export interface PiUsereqStatusState {
|
|
|
123
120
|
runStartTimeMs: number | undefined;
|
|
124
121
|
lastRunDurationMs: number | undefined;
|
|
125
122
|
totalRunDurationMs: number | undefined;
|
|
123
|
+
runtimeSoundLevel: PiNotifySoundLevel | undefined;
|
|
126
124
|
pendingPromptRequest: PiUsereqPromptRequest | undefined;
|
|
127
125
|
activePromptRequest: PiUsereqPromptRequest | undefined;
|
|
128
126
|
}
|
|
@@ -323,6 +321,17 @@ function createStatusThemeAdapter(theme: RawStatusTheme): StatusThemeAdapter {
|
|
|
323
321
|
};
|
|
324
322
|
}
|
|
325
323
|
|
|
324
|
+
/**
|
|
325
|
+
* @brief Resolves the active git branch value rendered in the status bar.
|
|
326
|
+
* @details Reads the current branch from the active context working directory on every status render so worktree switches and restored base-session renders expose the latest branch immediately. Runtime is dominated by git execution when the working directory belongs to a repository. Side effects include subprocess creation.
|
|
327
|
+
* @param[in] ctx {ExtensionContext} Active extension context.
|
|
328
|
+
* @return {string} Active branch name or `unknown` when unavailable.
|
|
329
|
+
* @satisfies REQ-121, REQ-283
|
|
330
|
+
*/
|
|
331
|
+
function resolveStatusBranchValue(ctx: ExtensionContext): string {
|
|
332
|
+
return resolveRuntimeGitBranchName(ctx.cwd);
|
|
333
|
+
}
|
|
334
|
+
|
|
326
335
|
/**
|
|
327
336
|
* @brief Normalizes one raw context-usage snapshot.
|
|
328
337
|
* @details Preserves the runtime token and context-window counts, derives a
|
|
@@ -370,12 +379,10 @@ function refreshContextUsage(
|
|
|
370
379
|
|
|
371
380
|
/**
|
|
372
381
|
* @brief Resolves the icon text for one normalized context-usage snapshot.
|
|
373
|
-
* @details Maps context usage to one fixed-width icon band so footer rendering
|
|
374
|
-
* remains compact and deterministic. Unavailable usage degrades to the `0%`
|
|
375
|
-
* icon. Runtime is O(1). No external state is mutated.
|
|
382
|
+
* @details Maps context usage to one fixed-width icon band so footer rendering remains compact and deterministic across the documented `0`, `>0-<25`, `>=25-<50`, `>=50-<75`, and `>=75` percent bands. Unavailable usage degrades to the `0%` icon. Runtime is O(1). No external state is mutated.
|
|
376
383
|
* @param[in] contextUsage {ContextUsage | undefined} Normalized context snapshot.
|
|
377
384
|
* @return {string} Fixed-width gauge icon text.
|
|
378
|
-
* @satisfies REQ-
|
|
385
|
+
* @satisfies REQ-122, REQ-284
|
|
379
386
|
*/
|
|
380
387
|
function resolveContextUsageIconText(
|
|
381
388
|
contextUsage: ContextUsage | undefined,
|
|
@@ -384,13 +391,13 @@ function resolveContextUsageIconText(
|
|
|
384
391
|
if (percent === undefined || percent === null || percent <= 0) {
|
|
385
392
|
return "▕_▏";
|
|
386
393
|
}
|
|
387
|
-
if (percent
|
|
394
|
+
if (percent < 25) {
|
|
388
395
|
return "▕▂▏";
|
|
389
396
|
}
|
|
390
|
-
if (percent
|
|
397
|
+
if (percent < 50) {
|
|
391
398
|
return "▕▄▏";
|
|
392
399
|
}
|
|
393
|
-
if (percent
|
|
400
|
+
if (percent < 75) {
|
|
394
401
|
return "▕▆▏";
|
|
395
402
|
}
|
|
396
403
|
return "▕█▏";
|
|
@@ -398,22 +405,22 @@ function resolveContextUsageIconText(
|
|
|
398
405
|
|
|
399
406
|
/**
|
|
400
407
|
* @brief Formats one icon-based context-usage gauge.
|
|
401
|
-
* @details Renders the documented
|
|
408
|
+
* @details Renders the documented gauge icon with the same non-error status-value theme token used by `status` below `90%`, switches to theme `error` for `>=90%`, and enables terminal blink only for `>=100%`. Runtime is O(1). No external state is mutated.
|
|
402
409
|
* @param[in] theme {StatusThemeAdapter} Normalized status theme.
|
|
403
410
|
* @param[in] contextUsage {ContextUsage | undefined} Normalized context snapshot.
|
|
404
411
|
* @return {string} Rendered fixed-width gauge icon.
|
|
405
|
-
* @satisfies REQ-
|
|
412
|
+
* @satisfies REQ-122, REQ-126, REQ-127, REQ-128, REQ-233, REQ-284
|
|
406
413
|
*/
|
|
407
414
|
function formatContextUsageBar(
|
|
408
415
|
theme: StatusThemeAdapter,
|
|
409
416
|
contextUsage: ContextUsage | undefined,
|
|
410
417
|
): string {
|
|
411
418
|
const percent = contextUsage?.percent ?? 0;
|
|
412
|
-
if (percent
|
|
419
|
+
if (percent >= 100) {
|
|
413
420
|
return theme.colorize("error", "\u001b[5m▕█▏\u001b[25m");
|
|
414
421
|
}
|
|
415
|
-
if (percent
|
|
416
|
-
return theme.colorize("
|
|
422
|
+
if (percent >= 90) {
|
|
423
|
+
return theme.colorize("error", "▕█▏");
|
|
417
424
|
}
|
|
418
425
|
return theme.value(resolveContextUsageIconText(contextUsage));
|
|
419
426
|
}
|
|
@@ -543,34 +550,48 @@ function didAgentEndAbort(messages: AgentEndEvent["messages"]): boolean {
|
|
|
543
550
|
);
|
|
544
551
|
}
|
|
545
552
|
|
|
553
|
+
/**
|
|
554
|
+
* @brief Resolves the active runtime sound level used by status and notify flows.
|
|
555
|
+
* @details Prefers the mutable runtime sound state, then falls back to the cached persisted boot value, and finally defaults to `none` before `session_start` loads configuration. Runtime is O(1). No external state is mutated.
|
|
556
|
+
* @param[in] state {PiUsereqStatusState} Mutable status state snapshot.
|
|
557
|
+
* @param[in] config {UseReqConfig | undefined} Cached project configuration.
|
|
558
|
+
* @return {PiNotifySoundLevel} Active runtime sound level.
|
|
559
|
+
* @satisfies REQ-180, REQ-285
|
|
560
|
+
*/
|
|
561
|
+
function resolvePiUsereqRuntimeSoundLevel(
|
|
562
|
+
state: PiUsereqStatusState,
|
|
563
|
+
config: UseReqConfig | undefined,
|
|
564
|
+
): PiNotifySoundLevel {
|
|
565
|
+
return state.runtimeSoundLevel ?? config?.["notify-sound"] ?? "none";
|
|
566
|
+
}
|
|
567
|
+
|
|
546
568
|
/**
|
|
547
569
|
* @brief Builds the full single-line pi-usereq status-bar payload.
|
|
548
|
-
* @details Renders status,
|
|
549
|
-
* @param[in] cwd {string} Runtime working directory used for context-path derivation.
|
|
570
|
+
* @details Renders status, branch, context, elapsed, and sound fields in the canonical order with dim bullet separators, workflow-state highlighting, the documented icon-based context gauge, and the active runtime sound level instead of the persisted boot value. Runtime is O(1). No external state is mutated.
|
|
550
571
|
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
551
572
|
* @param[in] theme {StatusThemeAdapter} Normalized status theme.
|
|
552
573
|
* @param[in] state {PiUsereqStatusState} Mutable status state snapshot.
|
|
574
|
+
* @param[in] branchName {string} Active git branch name shown in the footer.
|
|
553
575
|
* @param[in] nowMs {number} Current wall-clock time in milliseconds.
|
|
554
576
|
* @return {string} Single-line status-bar text.
|
|
555
|
-
* @satisfies REQ-109, REQ-112, REQ-120, REQ-121, REQ-123, REQ-124, REQ-125, REQ-126, REQ-127, REQ-128, REQ-
|
|
577
|
+
* @satisfies REQ-109, REQ-112, REQ-120, REQ-121, REQ-123, REQ-124, REQ-125, REQ-126, REQ-127, REQ-128, REQ-156, REQ-159, REQ-180, REQ-222, REQ-223, REQ-233, REQ-283, REQ-284
|
|
556
578
|
*/
|
|
557
579
|
function buildPiUsereqStatusText(
|
|
558
|
-
cwd: string,
|
|
559
580
|
config: UseReqConfig,
|
|
560
581
|
theme: StatusThemeAdapter,
|
|
561
582
|
state: PiUsereqStatusState,
|
|
583
|
+
branchName: string,
|
|
562
584
|
nowMs: number,
|
|
563
585
|
): string {
|
|
564
|
-
const currentPathText = formatRuntimePathForDisplay(getRuntimeContextPath(cwd));
|
|
565
586
|
const elapsedText = formatElapsedStatusValue(state, nowMs);
|
|
566
|
-
const soundText = config
|
|
587
|
+
const soundText = resolvePiUsereqRuntimeSoundLevel(state, config);
|
|
567
588
|
return [
|
|
568
589
|
formatRenderedStatusField(
|
|
569
590
|
theme,
|
|
570
591
|
"status",
|
|
571
592
|
formatWorkflowStateValue(theme, state.workflowState),
|
|
572
593
|
),
|
|
573
|
-
formatStatusField(theme, "
|
|
594
|
+
formatStatusField(theme, "branch", branchName),
|
|
574
595
|
formatRenderedStatusField(
|
|
575
596
|
theme,
|
|
576
597
|
"context",
|
|
@@ -626,7 +647,7 @@ function syncPiUsereqStatusTicker(
|
|
|
626
647
|
|
|
627
648
|
/**
|
|
628
649
|
* @brief Creates an empty pi-usereq status controller.
|
|
629
|
-
* @details Initializes the mutable status snapshot, including empty prompt-request tracking
|
|
650
|
+
* @details Initializes the mutable status snapshot, including empty prompt-request tracking and an unset runtime sound level that later loads from persisted config during `session_start`, and starts with no config, no context, and no live ticker. Runtime is O(1). No external state is mutated.
|
|
630
651
|
* @return {PiUsereqStatusController} New status controller.
|
|
631
652
|
* @satisfies DES-010
|
|
632
653
|
*/
|
|
@@ -640,6 +661,7 @@ export function createPiUsereqStatusController(): PiUsereqStatusController {
|
|
|
640
661
|
runStartTimeMs: undefined,
|
|
641
662
|
lastRunDurationMs: undefined,
|
|
642
663
|
totalRunDurationMs: undefined,
|
|
664
|
+
runtimeSoundLevel: undefined,
|
|
643
665
|
pendingPromptRequest: undefined,
|
|
644
666
|
activePromptRequest: undefined,
|
|
645
667
|
},
|
|
@@ -650,8 +672,9 @@ export function createPiUsereqStatusController(): PiUsereqStatusController {
|
|
|
650
672
|
/**
|
|
651
673
|
* @brief Stores the effective project configuration used by status rendering.
|
|
652
674
|
* @details Replaces the controller's cached configuration so later status
|
|
653
|
-
* renders reuse the latest docs, tests, source-path, and pi-notify
|
|
654
|
-
* without reading from disk on every event
|
|
675
|
+
* renders reuse the latest docs, tests, source-path, and persisted pi-notify
|
|
676
|
+
* values without reading from disk on every event, while leaving the active
|
|
677
|
+
* runtime sound level in `controller.state`. Runtime is O(1). Side effect:
|
|
655
678
|
* mutates `controller.config`.
|
|
656
679
|
* @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
|
|
657
680
|
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
@@ -664,13 +687,47 @@ export function setPiUsereqStatusConfig(
|
|
|
664
687
|
controller.config = config;
|
|
665
688
|
}
|
|
666
689
|
|
|
690
|
+
/**
|
|
691
|
+
* @brief Returns the active runtime sound level tracked by the status controller.
|
|
692
|
+
* @details Exposes the in-memory runtime sound state so shortcut handlers and prompt-end notification dispatch can stay decoupled from the persisted boot value stored in `.pi-usereq.json`. Runtime is O(1). No external state is mutated.
|
|
693
|
+
* @param[in] controller {PiUsereqStatusController} Mutable status controller.
|
|
694
|
+
* @return {PiNotifySoundLevel} Active runtime sound level.
|
|
695
|
+
* @satisfies REQ-180, REQ-285
|
|
696
|
+
*/
|
|
697
|
+
export function getPiUsereqRuntimeSoundLevel(
|
|
698
|
+
controller: PiUsereqStatusController,
|
|
699
|
+
): PiNotifySoundLevel {
|
|
700
|
+
return resolvePiUsereqRuntimeSoundLevel(controller.state, controller.config);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* @brief Stores one new runtime sound level and refreshes the status bar.
|
|
705
|
+
* @details Mutates only the in-memory runtime sound state so shortcut-driven sound changes do not update `.pi-usereq.json`, then re-renders the footer when an active extension context is available. Runtime is O(1). Side effect: mutates `controller.state.runtimeSoundLevel` and may update `ctx.ui` status.
|
|
706
|
+
* @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
|
|
707
|
+
* @param[in] runtimeSoundLevel {PiNotifySoundLevel} Next active runtime sound level.
|
|
708
|
+
* @param[in] ctx {ExtensionContext | undefined} Optional active extension context.
|
|
709
|
+
* @return {void} No return value.
|
|
710
|
+
* @satisfies REQ-180, REQ-286, REQ-287
|
|
711
|
+
*/
|
|
712
|
+
export function setPiUsereqRuntimeSoundLevel(
|
|
713
|
+
controller: PiUsereqStatusController,
|
|
714
|
+
runtimeSoundLevel: PiNotifySoundLevel,
|
|
715
|
+
ctx?: ExtensionContext,
|
|
716
|
+
): void {
|
|
717
|
+
controller.state.runtimeSoundLevel = runtimeSoundLevel;
|
|
718
|
+
const renderContext = ctx ?? controller.latestContext;
|
|
719
|
+
if (renderContext) {
|
|
720
|
+
renderPiUsereqStatus(controller, renderContext);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
667
724
|
/**
|
|
668
725
|
* @brief Renders the current pi-usereq status bar into the active UI context.
|
|
669
|
-
* @details Updates the controller's latest context pointer and writes the single-line status text only when configuration is available,
|
|
726
|
+
* @details Updates the controller's latest context pointer, refreshes the live `getContextUsage()` snapshot for direct render call sites that do not pass through `updateExtensionStatus(...)`, and writes the single-line status text only when configuration is available, including the active branch field, documented icon-based context gauge, and active runtime sound level. When pi has already invalidated the supplied context after session replacement or reload, the helper clears the stale cached context and returns without surfacing the stale-instance exception. Runtime is O(1) plus git execution for branch refresh. Side effect: mutates `controller.state.contextUsage` and `ctx.ui` status when the context is still active.
|
|
670
727
|
* @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
|
|
671
728
|
* @param[in] ctx {ExtensionContext} Active extension context.
|
|
672
729
|
* @return {void} No return value.
|
|
673
|
-
* @satisfies REQ-120, REQ-121, REQ-123, REQ-124, REQ-125, REQ-126, REQ-127, REQ-128, REQ-
|
|
730
|
+
* @satisfies REQ-118, REQ-119, REQ-120, REQ-121, REQ-123, REQ-124, REQ-125, REQ-126, REQ-127, REQ-128, REQ-159, REQ-180, REQ-233, REQ-280, REQ-283, REQ-284
|
|
674
731
|
*/
|
|
675
732
|
export function renderPiUsereqStatus(
|
|
676
733
|
controller: PiUsereqStatusController,
|
|
@@ -681,14 +738,16 @@ export function renderPiUsereqStatus(
|
|
|
681
738
|
return;
|
|
682
739
|
}
|
|
683
740
|
try {
|
|
741
|
+
refreshContextUsage(controller.state, ctx);
|
|
684
742
|
const theme = createStatusThemeAdapter(ctx.ui.theme as RawStatusTheme);
|
|
743
|
+
const branchName = resolveStatusBranchValue(ctx);
|
|
685
744
|
ctx.ui.setStatus(
|
|
686
745
|
"pi-usereq",
|
|
687
746
|
buildPiUsereqStatusText(
|
|
688
|
-
ctx.cwd,
|
|
689
747
|
controller.config,
|
|
690
748
|
theme,
|
|
691
749
|
controller.state,
|
|
750
|
+
branchName,
|
|
692
751
|
Date.now(),
|
|
693
752
|
),
|
|
694
753
|
);
|
|
@@ -727,13 +786,13 @@ export function setPiUsereqWorkflowState(
|
|
|
727
786
|
|
|
728
787
|
/**
|
|
729
788
|
* @brief Updates mutable status state for one intercepted lifecycle hook.
|
|
730
|
-
* @details Refreshes stored context usage on every hook, resets or restores persisted elapsed counters during `session_start`, restores persisted prompt-command metadata when the active session matches a forked execution session, resynchronizes that metadata on later lifecycle hooks so post-switch workflow transitions performed by the initiating command handler become visible to the replacement-session runtime, resets workflow state to `idle` for documented session-start reasons, starts run timing on `agent_start`, promotes pending prompt-request metadata into the active run, captures non-aborted run duration on `agent_end`, accumulates successful runtime into `Σ`, preserves in-memory prompt-command state plus process-scoped persistence across switch-triggered `session_shutdown`, tolerates stale post-replacement render contexts, synchronizes the live ticker, and re-renders the status bar when configuration is available. Runtime is O(n) in `agent_end` message count and otherwise O(1). Side effects include in-memory state mutation, interval scheduling, process-scoped persistence mutation, and footer-status updates.
|
|
789
|
+
* @details Refreshes stored context usage on every hook, resets or restores persisted elapsed counters during `session_start`, loads the active runtime sound level from persisted config during `session_start`, restores persisted prompt-command metadata when the active session matches a forked execution session, resynchronizes that metadata on later lifecycle hooks so post-switch workflow transitions performed by the initiating command handler become visible to the replacement-session runtime, resets workflow state to `idle` for documented session-start reasons, starts run timing on `agent_start`, promotes pending prompt-request metadata into the active run, captures non-aborted run duration on `agent_end`, accumulates successful runtime into `Σ`, preserves in-memory prompt-command state plus process-scoped persistence across switch-triggered `session_shutdown`, tolerates stale post-replacement render contexts, synchronizes the live ticker, and re-renders the status bar when configuration is available. Runtime is O(n) in `agent_end` message count and otherwise O(1). Side effects include in-memory state mutation, interval scheduling, process-scoped persistence mutation, and footer-status updates.
|
|
731
790
|
* @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
|
|
732
791
|
* @param[in] hookName {PiUsereqStatusHookName} Intercepted hook name.
|
|
733
792
|
* @param[in] event {unknown} Hook payload forwarded from the wrapper.
|
|
734
793
|
* @param[in] ctx {ExtensionContext} Active extension context.
|
|
735
794
|
* @return {void} No return value.
|
|
736
|
-
* @satisfies REQ-009, REQ-117, REQ-118, REQ-119, REQ-123, REQ-124, REQ-125, REQ-159, REQ-169, REQ-217, REQ-221, REQ-278, REQ-279, REQ-280
|
|
795
|
+
* @satisfies REQ-009, REQ-117, REQ-118, REQ-119, REQ-123, REQ-124, REQ-125, REQ-159, REQ-169, REQ-217, REQ-221, REQ-278, REQ-279, REQ-280, REQ-285
|
|
737
796
|
*/
|
|
738
797
|
export function updateExtensionStatus(
|
|
739
798
|
controller: PiUsereqStatusController,
|
|
@@ -752,6 +811,9 @@ export function updateExtensionStatus(
|
|
|
752
811
|
} else {
|
|
753
812
|
restorePersistedElapsedState(controller.state);
|
|
754
813
|
}
|
|
814
|
+
controller.state.runtimeSoundLevel = controller.config?.["notify-sound"]
|
|
815
|
+
?? controller.state.runtimeSoundLevel
|
|
816
|
+
?? "none";
|
|
755
817
|
const shouldResetWorkflowState = shouldResetWorkflowStateOnSessionStart(event);
|
|
756
818
|
if (shouldResetWorkflowState) {
|
|
757
819
|
controller.state.workflowState = "idle";
|
package/src/core/pi-notify.ts
CHANGED
|
@@ -110,7 +110,7 @@ export interface PiNotifyEventRequest {
|
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
112
|
* @brief Describes the configuration fields consumed by pi-notify helpers.
|
|
113
|
-
* @details Narrows the full project config to the
|
|
113
|
+
* @details Narrows the full project config to the notify, sound, and Pushover fields used by status rendering and prompt-end routing. Callers may override `notify-sound` with the active runtime sound level before dispatch. Compile-time only and introduces no runtime cost.
|
|
114
114
|
*/
|
|
115
115
|
export type PiNotifyConfigFields = Pick<
|
|
116
116
|
UseReqConfig,
|
|
@@ -363,10 +363,10 @@ export function formatPiNotifyPushoverStatus(config: Pick<UseReqConfig, "notify-
|
|
|
363
363
|
|
|
364
364
|
/**
|
|
365
365
|
* @brief Cycles one sound level through the canonical shortcut order.
|
|
366
|
-
* @details Advances
|
|
367
|
-
* @param[in] currentLevel {PiNotifySoundLevel} Current
|
|
368
|
-
* @return {PiNotifySoundLevel} Next sound level in the cycle.
|
|
369
|
-
* @satisfies REQ-
|
|
366
|
+
* @details Advances the active runtime sound state in the exact order `none -> low -> mid -> high -> none`, enabling deterministic shortcut toggling without mutating persisted boot configuration. Runtime is O(1). No external state is mutated.
|
|
367
|
+
* @param[in] currentLevel {PiNotifySoundLevel} Current active runtime sound level.
|
|
368
|
+
* @return {PiNotifySoundLevel} Next runtime sound level in the cycle.
|
|
369
|
+
* @satisfies REQ-286
|
|
370
370
|
*/
|
|
371
371
|
export function cyclePiNotifySoundLevel(currentLevel: PiNotifySoundLevel): PiNotifySoundLevel {
|
|
372
372
|
const currentIndex = PI_NOTIFY_SOUND_LEVELS.indexOf(currentLevel);
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export const PI_USEREQ_CUSTOM_TOOL_NAMES = [
|
|
12
12
|
"files-tokens",
|
|
13
|
-
"files-
|
|
13
|
+
"files-summarize",
|
|
14
14
|
"files-compress",
|
|
15
15
|
"files-search",
|
|
16
|
+
"summarize",
|
|
16
17
|
"references",
|
|
17
18
|
"compress",
|
|
18
19
|
"search",
|
|
@@ -51,9 +52,10 @@ export const PI_USEREQ_STARTUP_TOOL_NAMES = [
|
|
|
51
52
|
*/
|
|
52
53
|
export const PI_USEREQ_DEFAULT_ENABLED_TOOL_NAMES = [
|
|
53
54
|
"files-tokens",
|
|
54
|
-
"files-
|
|
55
|
+
"files-summarize",
|
|
55
56
|
"files-compress",
|
|
56
57
|
"files-search",
|
|
58
|
+
"summarize",
|
|
57
59
|
"references",
|
|
58
60
|
"compress",
|
|
59
61
|
"search",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file
|
|
3
|
-
* @brief Declares the canonical bundled `req-*`
|
|
4
|
-
* @details Centralizes prompt-command names shared by extension registration, configuration normalization, debug-menu rendering, and prompt-runtime orchestration. The module is side-effect free. Lookup cost is O(1) per exported constant access.
|
|
3
|
+
* @brief Declares the canonical bundled prompt-backed `req-*` command inventory.
|
|
4
|
+
* @details Centralizes only prompt-template-backed command names shared by extension registration, configuration normalization, debug-menu rendering, and prompt-runtime orchestration. Specialized slash commands such as `req-references` and `req-reset` are registered outside this inventory. The module is side-effect free. Lookup cost is O(1) per exported constant access.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @brief Lists bundled prompt-command names handled by the extension.
|
|
9
|
-
* @details Provides the single source of truth for `req-*`
|
|
8
|
+
* @brief Lists bundled prompt-backed command names handled by the extension.
|
|
9
|
+
* @details Provides the single source of truth for prompt-template-backed `req-*` registration, required-document routing, debug-prompt inventory derivation, and prompt-command worktree orchestration. Access complexity is O(1).
|
|
10
10
|
*/
|
|
11
11
|
export const PROMPT_COMMAND_NAMES = [
|
|
12
12
|
"analyze",
|
|
@@ -21,7 +21,6 @@ export const PROMPT_COMMAND_NAMES = [
|
|
|
21
21
|
"readme",
|
|
22
22
|
"recreate",
|
|
23
23
|
"refactor",
|
|
24
|
-
"references",
|
|
25
24
|
"renumber",
|
|
26
25
|
"workflow",
|
|
27
26
|
"write",
|