pi-usereq 0.76.0 → 0.77.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/README.md +1 -1
- package/package.json +1 -1
- package/src/core/config.ts +11 -16
- package/src/core/debug-runtime.ts +199 -45
- package/src/index.ts +37 -20
package/README.md
CHANGED
package/package.json
CHANGED
package/src/core/config.ts
CHANGED
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
normalizePiNotifyTemplateValue,
|
|
33
33
|
} from "./pi-notify.js";
|
|
34
34
|
import {
|
|
35
|
-
DEFAULT_DEBUG_ENABLED,
|
|
36
35
|
DEFAULT_DEBUG_LOG_FILE,
|
|
37
36
|
DEFAULT_DEBUG_LOG_ON_STATUS,
|
|
38
37
|
DEFAULT_DEBUG_PROMPTS_ENABLED,
|
|
@@ -40,7 +39,7 @@ import {
|
|
|
40
39
|
DEFAULT_DEBUG_STATUS_CHANGES,
|
|
41
40
|
DEFAULT_DEBUG_TOOL_COMMANDS_ENABLED,
|
|
42
41
|
DEFAULT_DEBUG_WORKFLOW_EVENTS,
|
|
43
|
-
|
|
42
|
+
getRuntimeDebugEnabled,
|
|
44
43
|
normalizeDebugEnabledPrompts,
|
|
45
44
|
normalizeDebugEnabledTools,
|
|
46
45
|
normalizeDebugLogFile,
|
|
@@ -149,7 +148,8 @@ interface GlobalStaticCheckLanguageConfig {
|
|
|
149
148
|
|
|
150
149
|
/**
|
|
151
150
|
* @brief Defines the persisted local pi-usereq configuration schema.
|
|
152
|
-
* @details Captures project-scoped directory, debug, and static-check enablement fields written to `<base-path>/.pi-usereq.json` while excluding global notification, tool, git, and checker-command settings. The interface is compile-time only and introduces no runtime side effects.
|
|
151
|
+
* @details Captures project-scoped directory, debug, and static-check enablement fields written to `<base-path>/.pi-usereq.json` while excluding the runtime-only `DEBUG_ENABLED` flag and global notification, tool, git, and checker-command settings. The interface is compile-time only and introduces no runtime side effects.
|
|
152
|
+
* @satisfies REQ-426
|
|
153
153
|
*/
|
|
154
154
|
interface UseReqLocalConfig {
|
|
155
155
|
"docs-dir": string;
|
|
@@ -159,7 +159,6 @@ interface UseReqLocalConfig {
|
|
|
159
159
|
"context-files-references": boolean;
|
|
160
160
|
"context-files-workflow": boolean;
|
|
161
161
|
"static-check": Record<string, LocalStaticCheckLanguageConfig>;
|
|
162
|
-
DEBUG_ENABLED: "enable" | "disable";
|
|
163
162
|
DEBUG_LOG_FILE: string;
|
|
164
163
|
DEBUG_PROMPTS_ENABLED: DebugPromptsEnabled;
|
|
165
164
|
DEBUG_PROMPTS_LOG_PATH: string;
|
|
@@ -587,7 +586,7 @@ export function getGlobalConfigPath(): string {
|
|
|
587
586
|
* @details Populates canonical docs/test/source directories, derives local static-check enable defaults from the supplied global checker definitions, and seeds documented debug defaults including tool-wrapper command registration without any cross-project fields. Runtime is O(l). No filesystem side effects occur.
|
|
588
587
|
* @param[in] globalStaticCheckConfig {Record<string, GlobalStaticCheckLanguageConfig>} Global checker definitions used to derive local enable defaults.
|
|
589
588
|
* @return {UseReqLocalConfig} Fresh default local configuration object.
|
|
590
|
-
* @satisfies CTN-019, REQ-328, REQ-413, REQ-414
|
|
589
|
+
* @satisfies CTN-013, CTN-019, REQ-328, REQ-413, REQ-414, REQ-426
|
|
591
590
|
*/
|
|
592
591
|
function getDefaultLocalConfig(
|
|
593
592
|
globalStaticCheckConfig: Record<string, GlobalStaticCheckLanguageConfig>,
|
|
@@ -600,7 +599,6 @@ function getDefaultLocalConfig(
|
|
|
600
599
|
"context-files-references": DEFAULT_CONTEXT_FILES_FLAG,
|
|
601
600
|
"context-files-workflow": DEFAULT_CONTEXT_FILES_FLAG,
|
|
602
601
|
"static-check": getDefaultLocalStaticCheckConfig(globalStaticCheckConfig),
|
|
603
|
-
DEBUG_ENABLED: DEFAULT_DEBUG_ENABLED,
|
|
604
602
|
DEBUG_LOG_FILE: DEFAULT_DEBUG_LOG_FILE,
|
|
605
603
|
DEBUG_PROMPTS_ENABLED: DEFAULT_DEBUG_PROMPTS_ENABLED,
|
|
606
604
|
DEBUG_PROMPTS_LOG_PATH: DEFAULT_DEBUG_PROMPTS_LOG_PATH,
|
|
@@ -652,11 +650,11 @@ function getDefaultGlobalConfig(): UseReqGlobalConfig {
|
|
|
652
650
|
|
|
653
651
|
/**
|
|
654
652
|
* @brief Merges persisted local and global configuration scopes into the effective runtime config.
|
|
655
|
-
* @details Normalizes local directories, combines local static-check enable flags with global checker arrays, resolves effective worktree disablement when automatic git commit is off, normalizes debug and notification fields including tool-wrapper command registration, and disables Pushover until both credentials are populated. Runtime is O(l + c + p). No external state is mutated.
|
|
653
|
+
* @details Normalizes local directories, combines local static-check enable flags with global checker arrays, resolves effective worktree disablement when automatic git commit is off, normalizes debug and notification fields including tool-wrapper command registration, sources the runtime-only `DEBUG_ENABLED` flag from the process-scoped debug store, and disables Pushover until both credentials are populated. Runtime is O(l + c + p). No external state is mutated.
|
|
656
654
|
* @param[in] localConfig {UseReqLocalConfig} Persisted local configuration.
|
|
657
655
|
* @param[in] globalConfig {UseReqGlobalConfig} Persisted global configuration.
|
|
658
656
|
* @return {UseReqConfig} Effective merged configuration.
|
|
659
|
-
* @satisfies REQ-328, REQ-413, REQ-414
|
|
657
|
+
* @satisfies REQ-236, REQ-328, REQ-413, REQ-414, REQ-426
|
|
660
658
|
*/
|
|
661
659
|
function mergeConfigScopes(
|
|
662
660
|
localConfig: UseReqLocalConfig,
|
|
@@ -691,7 +689,7 @@ function mergeConfigScopes(
|
|
|
691
689
|
AUTO_GIT_COMMIT: autoGitCommit,
|
|
692
690
|
GIT_WORKTREE_ENABLED: gitWorktreeEnabled,
|
|
693
691
|
GIT_WORKTREE_PREFIX: normalizeGitWorktreePrefix(globalConfig.GIT_WORKTREE_PREFIX),
|
|
694
|
-
DEBUG_ENABLED:
|
|
692
|
+
DEBUG_ENABLED: getRuntimeDebugEnabled(),
|
|
695
693
|
DEBUG_LOG_FILE: normalizeDebugLogFile(localConfig.DEBUG_LOG_FILE),
|
|
696
694
|
DEBUG_PROMPTS_ENABLED: normalizeDebugPromptsEnabled(localConfig.DEBUG_PROMPTS_ENABLED),
|
|
697
695
|
DEBUG_PROMPTS_LOG_PATH: normalizeDebugPromptsLogPath(localConfig.DEBUG_PROMPTS_LOG_PATH),
|
|
@@ -862,11 +860,11 @@ function normalizeGlobalStaticCheckConfig(
|
|
|
862
860
|
|
|
863
861
|
/**
|
|
864
862
|
* @brief Loads and sanitizes the persisted local configuration.
|
|
865
|
-
* @details Returns defaults when `<base-path>/.pi-usereq.json` is absent. Otherwise parses the local JSON payload, normalizes project-scoped directory, debug, tool-wrapper command registration, and static-check enable fields, and ignores misplaced global keys without migration. Runtime is O(n) in file size. Side effects are limited to filesystem reads.
|
|
863
|
+
* @details Returns defaults when `<base-path>/.pi-usereq.json` is absent. Otherwise parses the local JSON payload, normalizes project-scoped directory, debug, tool-wrapper command registration, and static-check enable fields, ignores any persisted `DEBUG_ENABLED` payload, and ignores misplaced global keys without migration. Runtime is O(n) in file size. Side effects are limited to filesystem reads.
|
|
866
864
|
* @param[in] projectBase {string} Absolute project root path.
|
|
867
865
|
* @param[in] defaultStaticCheckConfig {Record<string, LocalStaticCheckLanguageConfig>} Local static-check enable defaults derived from the current global checker map.
|
|
868
866
|
* @return {UseReqLocalConfig} Sanitized local configuration.
|
|
869
|
-
* @satisfies CTN-019, REQ-328, REQ-413, REQ-414
|
|
867
|
+
* @satisfies CTN-019, REQ-328, REQ-413, REQ-414, REQ-426
|
|
870
868
|
*/
|
|
871
869
|
function loadLocalConfig(
|
|
872
870
|
projectBase: string,
|
|
@@ -883,7 +881,6 @@ function loadLocalConfig(
|
|
|
883
881
|
"context-files-references": DEFAULT_CONTEXT_FILES_FLAG,
|
|
884
882
|
"context-files-workflow": DEFAULT_CONTEXT_FILES_FLAG,
|
|
885
883
|
"static-check": normalizeLocalStaticCheckConfig(undefined, defaultStaticCheckConfig),
|
|
886
|
-
DEBUG_ENABLED: DEFAULT_DEBUG_ENABLED,
|
|
887
884
|
DEBUG_LOG_FILE: DEFAULT_DEBUG_LOG_FILE,
|
|
888
885
|
DEBUG_PROMPTS_ENABLED: DEFAULT_DEBUG_PROMPTS_ENABLED,
|
|
889
886
|
DEBUG_PROMPTS_LOG_PATH: DEFAULT_DEBUG_PROMPTS_LOG_PATH,
|
|
@@ -915,7 +912,6 @@ function loadLocalConfig(
|
|
|
915
912
|
"context-files-references": normalizeContextFilesFlag(data["context-files-references"]),
|
|
916
913
|
"context-files-workflow": normalizeContextFilesFlag(data["context-files-workflow"]),
|
|
917
914
|
"static-check": normalizeLocalStaticCheckConfig(data["static-check"], defaultStaticCheckConfig),
|
|
918
|
-
DEBUG_ENABLED: normalizeDebugEnabled(data.DEBUG_ENABLED),
|
|
919
915
|
DEBUG_LOG_FILE: normalizeDebugLogFile(data.DEBUG_LOG_FILE),
|
|
920
916
|
DEBUG_PROMPTS_ENABLED: normalizeDebugPromptsEnabled(data.DEBUG_PROMPTS_ENABLED),
|
|
921
917
|
DEBUG_PROMPTS_LOG_PATH: normalizeDebugPromptsLogPath(data.DEBUG_PROMPTS_LOG_PATH),
|
|
@@ -995,10 +991,10 @@ export function loadConfig(projectBase: string): UseReqConfig {
|
|
|
995
991
|
|
|
996
992
|
/**
|
|
997
993
|
* @brief Builds the persisted local configuration payload.
|
|
998
|
-
* @details Copies only project-scoped keys into a fresh object so runtime-derived metadata
|
|
994
|
+
* @details Copies only project-scoped keys into a fresh object so runtime-derived metadata, the runtime-only `DEBUG_ENABLED` flag, and global checker, tool, git, and notification fields never reach `.pi-usereq.json`, while preserving the debug tool-wrapper command flag beside other persisted local debug settings. Runtime is O(n) in config size. No external state is mutated.
|
|
999
995
|
* @param[in] config {UseReqConfig} Effective configuration object.
|
|
1000
996
|
* @return {UseReqLocalConfig} Persistable local configuration payload.
|
|
1001
|
-
* @satisfies CTN-012, CTN-013, CTN-019, REQ-104, REQ-146, REQ-249, REQ-316, REQ-277, REQ-328, REQ-413, REQ-414
|
|
997
|
+
* @satisfies CTN-012, CTN-013, CTN-019, REQ-104, REQ-146, REQ-249, REQ-316, REQ-277, REQ-328, REQ-413, REQ-414, REQ-426
|
|
1002
998
|
*/
|
|
1003
999
|
function buildPersistedLocalConfig(config: UseReqConfig): UseReqLocalConfig {
|
|
1004
1000
|
const normalizedSrcDir = config["src-dir"]
|
|
@@ -1022,7 +1018,6 @@ function buildPersistedLocalConfig(config: UseReqConfig): UseReqLocalConfig {
|
|
|
1022
1018
|
),
|
|
1023
1019
|
]),
|
|
1024
1020
|
),
|
|
1025
|
-
DEBUG_ENABLED: normalizeDebugEnabled(config.DEBUG_ENABLED),
|
|
1026
1021
|
DEBUG_LOG_FILE: normalizeDebugLogFile(config.DEBUG_LOG_FILE),
|
|
1027
1022
|
DEBUG_PROMPTS_ENABLED: normalizeDebugPromptsEnabled(config.DEBUG_PROMPTS_ENABLED),
|
|
1028
1023
|
DEBUG_PROMPTS_LOG_PATH: normalizeDebugPromptsLogPath(config.DEBUG_PROMPTS_LOG_PATH),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file
|
|
3
3
|
* @brief Declares debug inventories, normalizers, and JSON log persistence helpers.
|
|
4
|
-
* @details Centralizes debug-menu selector inventories, config-field normalization, workflow-status gating, append-only JSON log writing for tool, prompt, and dedicated workflow debug events, process-scoped capture of the exact `before_provider_request` provider payload for active prompt runs, and error-stage provider payload dumps gated by `after_provider_response` error statuses. Runtime is dominated by JSON serialization plus filesystem I/O during log writes. Side effects include directory creation and file overwrite when debug entries are appended.
|
|
4
|
+
* @details Centralizes debug-menu selector inventories, config-field normalization, the process-scoped runtime debug-enable state, workflow-status gating, append-only JSON log writing for tool, prompt, and dedicated workflow debug events, process-scoped capture of the exact `before_provider_request` provider payload for active prompt runs, and error-stage provider payload dumps gated by `after_provider_response` error statuses. Runtime is dominated by JSON serialization plus filesystem I/O during log writes. Side effects include directory creation and file overwrite when debug entries are appended.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import fs from "node:fs";
|
|
@@ -24,6 +24,49 @@ import {
|
|
|
24
24
|
*/
|
|
25
25
|
export const DEFAULT_DEBUG_ENABLED = "disable" as const;
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @brief Describes the process-scoped runtime debug-enable state persisted across session rebinds.
|
|
29
|
+
* @details Stores the user-toggled runtime `Debug` flag on `globalThis` because pi rebinds extension modules for `/new`, `/resume`, `/fork`, and `/reload` while the hosting process persists across those operations; the flag therefore survives ctrl+N session forks and `req-reset` but resets to `disable` when a fresh pi CLI process starts. The interface is compile-time only and introduces no runtime cost.
|
|
30
|
+
* @satisfies REQ-236, REQ-426
|
|
31
|
+
*/
|
|
32
|
+
interface ProcessScopedDebugEnabledStore {
|
|
33
|
+
runtimeDebugEnabled: "enable" | "disable" | undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @brief Returns the process-scoped runtime debug-enable store.
|
|
38
|
+
* @details Lazily initializes one `globalThis` record so session rebinds reuse the toggled runtime debug mode instead of resetting it to the persisted default. Runtime is O(1). Side effect: initializes process-scoped state on first access.
|
|
39
|
+
* @return {ProcessScopedDebugEnabledStore} Mutable process-scoped runtime debug store.
|
|
40
|
+
*/
|
|
41
|
+
function getProcessScopedDebugEnabledStore(): ProcessScopedDebugEnabledStore {
|
|
42
|
+
const globalScope = globalThis as typeof globalThis & { __piUsereqDebugEnabledStore?: ProcessScopedDebugEnabledStore };
|
|
43
|
+
if (!globalScope.__piUsereqDebugEnabledStore) {
|
|
44
|
+
globalScope.__piUsereqDebugEnabledStore = { runtimeDebugEnabled: undefined };
|
|
45
|
+
}
|
|
46
|
+
return globalScope.__piUsereqDebugEnabledStore;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @brief Resolves the runtime debug-enable mode for the current pi host process.
|
|
51
|
+
* @details Returns the process-scoped toggled value when present and the documented `disable` default otherwise, so every fresh pi CLI process starts with debug logging disabled regardless of any stale persisted payload. Runtime is O(1). No external state is mutated.
|
|
52
|
+
* @return {"enable" | "disable"} Effective runtime debug-enable mode.
|
|
53
|
+
* @satisfies REQ-236
|
|
54
|
+
*/
|
|
55
|
+
export function getRuntimeDebugEnabled(): "enable" | "disable" {
|
|
56
|
+
return getProcessScopedDebugEnabledStore().runtimeDebugEnabled ?? DEFAULT_DEBUG_ENABLED;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @brief Stores one user-toggled runtime debug-enable mode for the current pi host process.
|
|
61
|
+
* @details Mutates only the process-scoped runtime store so `Debug` menu toggles survive session rebinds without reaching persisted local or global configuration files. Runtime is O(1). Side effect: mutates process-scoped runtime state.
|
|
62
|
+
* @param[in] runtimeDebugEnabled {"enable" | "disable"} Next runtime debug-enable mode.
|
|
63
|
+
* @return {void} No return value.
|
|
64
|
+
* @satisfies REQ-236, REQ-426
|
|
65
|
+
*/
|
|
66
|
+
export function setRuntimeDebugEnabled(runtimeDebugEnabled: "enable" | "disable"): void {
|
|
67
|
+
getProcessScopedDebugEnabledStore().runtimeDebugEnabled = runtimeDebugEnabled;
|
|
68
|
+
}
|
|
69
|
+
|
|
27
70
|
/**
|
|
28
71
|
* @brief Defines the default debug log file value.
|
|
29
72
|
* @details New configurations write debug JSON entries to `/tmp/PI-useReq.json` unless the user overrides the path. Access complexity is O(1).
|
|
@@ -442,10 +485,10 @@ export function shouldLogDebugPromptWorkflowEvent(
|
|
|
442
485
|
|
|
443
486
|
/**
|
|
444
487
|
* @brief Tests whether one dispatched prompt content file should be written.
|
|
445
|
-
* @details Requires global debug enablement
|
|
488
|
+
* @details Requires global debug enablement plus explicit prompt-content debug enablement before any filesystem work occurs; prompt-content logging is fully subordinate to the global `Debug` flag and exempt from the `DEBUG_LOG_ON_STATUS` workflow-state filter so enabled runs always save their debug files. Runtime is O(1). No external state is mutated.
|
|
446
489
|
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
447
|
-
* @param[in] workflowState {DebugWorkflowState} Current workflow state.
|
|
448
|
-
* @param[in] promptName {PromptCommandName} Bundled prompt name.
|
|
490
|
+
* @param[in] workflowState {DebugWorkflowState} Current workflow state; retained for signature compatibility and excluded from gating per REQ-416.
|
|
491
|
+
* @param[in] promptName {PromptCommandName} Bundled prompt name; retained for signature compatibility.
|
|
449
492
|
* @return {boolean} `true` when the prompt content file should be written.
|
|
450
493
|
* @satisfies REQ-413, REQ-416
|
|
451
494
|
*/
|
|
@@ -455,8 +498,7 @@ export function shouldLogDebugPromptContent(
|
|
|
455
498
|
promptName: PromptCommandName,
|
|
456
499
|
): boolean {
|
|
457
500
|
return normalizeDebugEnabled(config.DEBUG_ENABLED) === "enable"
|
|
458
|
-
&& normalizeDebugPromptsEnabled(config.DEBUG_PROMPTS_ENABLED) === "enable"
|
|
459
|
-
&& matchesDebugWorkflowState(normalizeDebugLogOnStatus(config.DEBUG_LOG_ON_STATUS), workflowState);
|
|
501
|
+
&& normalizeDebugPromptsEnabled(config.DEBUG_PROMPTS_ENABLED) === "enable";
|
|
460
502
|
}
|
|
461
503
|
|
|
462
504
|
/**
|
|
@@ -681,21 +723,53 @@ export function formatPromptDebugFileName(
|
|
|
681
723
|
}
|
|
682
724
|
|
|
683
725
|
/**
|
|
684
|
-
* @brief
|
|
685
|
-
* @details
|
|
726
|
+
* @brief Builds one command-invocation summary debug filename for one bundled prompt.
|
|
727
|
+
* @details Appends the `-request` suffix to the shared `<timestamp>-<req-command>` base so every saved command invocation summary stays attributable to the originating `/req-*` prompt. Runtime is O(1). No external state is mutated.
|
|
728
|
+
* @param[in] promptName {PromptCommandName} Bundled prompt name.
|
|
729
|
+
* @param[in] date {Date} Write-time timestamp. Defaults to the current wall-clock time.
|
|
730
|
+
* @return {string} Prompt debug filename in the `<timestamp>-<req-command>-request` shape.
|
|
731
|
+
* @satisfies REQ-417, REQ-427
|
|
732
|
+
*/
|
|
733
|
+
export function formatPromptDebugRequestFileName(
|
|
734
|
+
promptName: PromptCommandName,
|
|
735
|
+
date = new Date(),
|
|
736
|
+
): string {
|
|
737
|
+
return `${formatPromptDebugFileName(promptName, date)}-request`;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* @brief Builds one dispatched-prompt content debug filename for one bundled prompt.
|
|
742
|
+
* @details Appends the `-prompt` suffix to the shared `<timestamp>-<req-command>` base so every saved initial LLM prompt stays attributable to the originating `/req-*` prompt. Runtime is O(1). No external state is mutated.
|
|
743
|
+
* @param[in] promptName {PromptCommandName} Bundled prompt name.
|
|
744
|
+
* @param[in] date {Date} Write-time timestamp. Defaults to the current wall-clock time.
|
|
745
|
+
* @return {string} Prompt debug filename in the `<timestamp>-<req-command>-prompt` shape.
|
|
746
|
+
* @satisfies REQ-417, REQ-418
|
|
747
|
+
*/
|
|
748
|
+
export function formatPromptDebugPromptFileName(
|
|
749
|
+
promptName: PromptCommandName,
|
|
750
|
+
date = new Date(),
|
|
751
|
+
): string {
|
|
752
|
+
return `${formatPromptDebugFileName(promptName, date)}-prompt`;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* @brief Writes one gated prompt debug file under the configured prompt log directory.
|
|
757
|
+
* @details Applies the global-debug plus prompt-debug gating, creates the configured prompt log directory, and writes the supplied text into the requested filename so dispatched-prompt artifacts can be replayed from the pi CLI without pi-usereq installed. Runtime is dominated by one directory creation plus one file write when enabled and O(1) otherwise. Side effects include directory creation and file creation only for enabled matching entries.
|
|
686
758
|
* @param[in] projectBase {string} Absolute original project base path.
|
|
687
759
|
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
688
|
-
* @param[in] workflowState {DebugWorkflowState} Current workflow state.
|
|
760
|
+
* @param[in] workflowState {DebugWorkflowState} Current workflow state; excluded from gating per REQ-416.
|
|
689
761
|
* @param[in] promptName {PromptCommandName} Bundled prompt name.
|
|
690
|
-
* @param[in]
|
|
691
|
-
* @
|
|
692
|
-
* @
|
|
762
|
+
* @param[in] fileName {string} Target filename under the resolved prompt log directory.
|
|
763
|
+
* @param[in] content {string} Exact text to persist.
|
|
764
|
+
* @return {boolean} `true` when the file is written; otherwise `false`.
|
|
765
|
+
* @satisfies REQ-416
|
|
693
766
|
*/
|
|
694
|
-
|
|
767
|
+
function writePromptDebugFile(
|
|
695
768
|
projectBase: string,
|
|
696
769
|
config: UseReqConfig,
|
|
697
770
|
workflowState: DebugWorkflowState,
|
|
698
771
|
promptName: PromptCommandName,
|
|
772
|
+
fileName: string,
|
|
699
773
|
content: string,
|
|
700
774
|
): boolean {
|
|
701
775
|
if (!shouldLogDebugPromptContent(config, workflowState, promptName)) {
|
|
@@ -704,20 +778,79 @@ export function logDebugPromptContent(
|
|
|
704
778
|
const logDirectory = resolveDebugPromptsLogPath(projectBase, config);
|
|
705
779
|
try {
|
|
706
780
|
fs.mkdirSync(logDirectory, { recursive: true });
|
|
707
|
-
fs.writeFileSync(path.join(logDirectory,
|
|
781
|
+
fs.writeFileSync(path.join(logDirectory, fileName), content, "utf8");
|
|
708
782
|
return true;
|
|
709
783
|
} catch {
|
|
710
784
|
return false;
|
|
711
785
|
}
|
|
712
786
|
}
|
|
713
787
|
|
|
788
|
+
/**
|
|
789
|
+
* @brief Writes one command invocation summary debug file when prompt debug logging is enabled.
|
|
790
|
+
* @details Persists the exact summary text displayed on screen into one `<timestamp>-<req-command>-request` file so the `/req-*` invocation headers survive beside the dispatched prompt. Runtime is dominated by one directory creation plus one file write when enabled and O(1) otherwise. Side effects include directory creation and file creation only for enabled matching entries.
|
|
791
|
+
* @param[in] projectBase {string} Absolute original project base path.
|
|
792
|
+
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
793
|
+
* @param[in] workflowState {DebugWorkflowState} Current workflow state; excluded from gating per REQ-416.
|
|
794
|
+
* @param[in] promptName {PromptCommandName} Bundled prompt name.
|
|
795
|
+
* @param[in] requestText {string} Exact command invocation summary text displayed on screen.
|
|
796
|
+
* @return {boolean} `true` when the request file is written; otherwise `false`.
|
|
797
|
+
* @satisfies REQ-416, REQ-417, REQ-427, REQ-428
|
|
798
|
+
*/
|
|
799
|
+
export function logDebugPromptRequest(
|
|
800
|
+
projectBase: string,
|
|
801
|
+
config: UseReqConfig,
|
|
802
|
+
workflowState: DebugWorkflowState,
|
|
803
|
+
promptName: PromptCommandName,
|
|
804
|
+
requestText: string,
|
|
805
|
+
): boolean {
|
|
806
|
+
return writePromptDebugFile(
|
|
807
|
+
projectBase,
|
|
808
|
+
config,
|
|
809
|
+
workflowState,
|
|
810
|
+
promptName,
|
|
811
|
+
formatPromptDebugRequestFileName(promptName),
|
|
812
|
+
requestText,
|
|
813
|
+
);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* @brief Writes one dispatched prompt content file when prompt debug logging is enabled.
|
|
818
|
+
* @details Persists the exact rendered prompt content delivered through `sendMessage` or `sendUserMessage` into one `<timestamp>-<req-command>-prompt` file so the send can be replayed from the pi CLI without pi-usereq installed. Runtime is dominated by one directory creation plus one file write when enabled and O(1) otherwise. Side effects include directory creation and file creation only for enabled matching entries.
|
|
819
|
+
* @param[in] projectBase {string} Absolute original project base path.
|
|
820
|
+
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
821
|
+
* @param[in] workflowState {DebugWorkflowState} Current workflow state; excluded from gating per REQ-416.
|
|
822
|
+
* @param[in] promptName {PromptCommandName} Bundled prompt name.
|
|
823
|
+
* @param[in] content {string} Exact rendered prompt content delivered through `sendMessage` or `sendUserMessage`.
|
|
824
|
+
* @return {boolean} `true` when the prompt content file is written; otherwise `false`.
|
|
825
|
+
* @satisfies REQ-416, REQ-417, REQ-418, REQ-428
|
|
826
|
+
*/
|
|
827
|
+
export function logDebugPromptContent(
|
|
828
|
+
projectBase: string,
|
|
829
|
+
config: UseReqConfig,
|
|
830
|
+
workflowState: DebugWorkflowState,
|
|
831
|
+
promptName: PromptCommandName,
|
|
832
|
+
content: string,
|
|
833
|
+
): boolean {
|
|
834
|
+
return writePromptDebugFile(
|
|
835
|
+
projectBase,
|
|
836
|
+
config,
|
|
837
|
+
workflowState,
|
|
838
|
+
promptName,
|
|
839
|
+
formatPromptDebugPromptFileName(promptName),
|
|
840
|
+
content,
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
|
|
714
844
|
/**
|
|
715
845
|
* @brief Describes one process-scoped captured provider request payload bound to an active prompt run.
|
|
716
|
-
* @details Pairs the bundled prompt name
|
|
846
|
+
* @details Pairs the bundled prompt name, the serialization of the exact `before_provider_request` payload, the original project base, and the resolved prompt log directory so a later `after_provider_response` error status can dump the failing request verbatim without live controller state, cached configuration, or live provider objects. The interface is compile-time only and introduces no runtime cost.
|
|
847
|
+
* @satisfies REQ-421
|
|
717
848
|
*/
|
|
718
849
|
interface CapturedPromptErrorPayload {
|
|
719
850
|
promptName: PromptCommandName;
|
|
720
851
|
payloadText: string;
|
|
852
|
+
projectBase: string;
|
|
853
|
+
logDirectory: string;
|
|
721
854
|
}
|
|
722
855
|
|
|
723
856
|
/**
|
|
@@ -758,66 +891,77 @@ export function formatPromptDebugErrorFileName(
|
|
|
758
891
|
return `${formatPromptDebugTimestamp(date)}-${getDebugPromptName(promptName)}-error-${errorCode}`;
|
|
759
892
|
}
|
|
760
893
|
|
|
894
|
+
/**
|
|
895
|
+
* @brief Serializes one provider request payload into deterministic text.
|
|
896
|
+
* @details Pretty-prints the payload as JSON while degrading circular references into one `[Circular]` token and bigint values into decimal strings so serialization failures never discard the capture. Runtime is O(n) in serialized payload size. No external state is mutated.
|
|
897
|
+
* @param[in] payload {unknown} Exact `before_provider_request` provider request payload.
|
|
898
|
+
* @return {string} Serialized payload text; the empty string when the payload serializes to nothing.
|
|
899
|
+
*/
|
|
900
|
+
function serializePromptProviderPayload(payload: unknown): string {
|
|
901
|
+
const seenObjects = new WeakSet<object>();
|
|
902
|
+
return JSON.stringify(
|
|
903
|
+
payload,
|
|
904
|
+
(_key: string, value: unknown) => {
|
|
905
|
+
if (typeof value === "bigint") {
|
|
906
|
+
return value.toString();
|
|
907
|
+
}
|
|
908
|
+
if (typeof value === "object" && value !== null) {
|
|
909
|
+
if (seenObjects.has(value)) {
|
|
910
|
+
return "[Circular]";
|
|
911
|
+
}
|
|
912
|
+
seenObjects.add(value);
|
|
913
|
+
}
|
|
914
|
+
return value;
|
|
915
|
+
},
|
|
916
|
+
2,
|
|
917
|
+
) ?? "";
|
|
918
|
+
}
|
|
919
|
+
|
|
761
920
|
/**
|
|
762
921
|
* @brief Captures one exact provider request payload for the active prompt run when prompt debug logging is enabled.
|
|
763
|
-
* @details Applies the
|
|
922
|
+
* @details Applies the global-debug plus prompt-debug gating, serializes the exact `before_provider_request` payload through the cycle-safe serializer, and stores the prompt name, payload text, original project base, and resolved prompt log directory in the process-scoped capture store so the payload survives session replacement and later error-stage writes require no live workflow state or cached configuration. Runtime is O(n) in serialized payload size when enabled and O(1) otherwise. Side effect: mutates the process-scoped capture store for enabled matching requests.
|
|
764
923
|
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
765
|
-
* @param[in] workflowState {DebugWorkflowState} Current workflow state.
|
|
766
924
|
* @param[in] promptName {PromptCommandName} Active bundled prompt name.
|
|
925
|
+
* @param[in] projectBase {string} Absolute original project base path used to resolve the prompt log directory.
|
|
767
926
|
* @param[in] payload {unknown} Exact `before_provider_request` provider request payload.
|
|
768
927
|
* @return {void} No return value.
|
|
769
928
|
* @satisfies REQ-416, REQ-421
|
|
770
929
|
*/
|
|
771
930
|
export function capturePromptProviderRequestForDebug(
|
|
772
931
|
config: UseReqConfig,
|
|
773
|
-
workflowState: DebugWorkflowState,
|
|
774
932
|
promptName: PromptCommandName,
|
|
933
|
+
projectBase: string,
|
|
775
934
|
payload: unknown,
|
|
776
935
|
): void {
|
|
777
|
-
if (!shouldLogDebugPromptContent(config,
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
let payloadText: string;
|
|
781
|
-
try {
|
|
782
|
-
payloadText = JSON.stringify(payload, null, 2) ?? "";
|
|
783
|
-
} catch {
|
|
936
|
+
if (!shouldLogDebugPromptContent(config, "unknown", promptName)) {
|
|
784
937
|
return;
|
|
785
938
|
}
|
|
786
|
-
getProcessScopedPromptErrorCaptureStore().capturedPromptErrorPayload = {
|
|
939
|
+
getProcessScopedPromptErrorCaptureStore().capturedPromptErrorPayload = {
|
|
940
|
+
promptName,
|
|
941
|
+
payloadText: serializePromptProviderPayload(payload),
|
|
942
|
+
projectBase,
|
|
943
|
+
logDirectory: resolveDebugPromptsLogPath(projectBase, config),
|
|
944
|
+
};
|
|
787
945
|
}
|
|
788
946
|
|
|
789
947
|
/**
|
|
790
948
|
* @brief Writes the captured provider request payload as one error-stage prompt debug file for the failing prompt.
|
|
791
|
-
* @details Consumes the process-scoped capture
|
|
792
|
-
* @param[in] projectBase {string} Absolute original project base path.
|
|
793
|
-
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
794
|
-
* @param[in] workflowState {DebugWorkflowState} Current workflow state.
|
|
795
|
-
* @param[in] promptName {PromptCommandName} Active bundled prompt name.
|
|
949
|
+
* @details Consumes the process-scoped capture, discards it after every write attempt so stale payloads never reach later runs, rejects failing statuses below 400, and writes the exact captured payload into one `<timestamp>-<req-command>-error-<status>` file inside the captured log directory beside the initial dispatched prompt artifacts. All write inputs come from the capture itself, so the flush requires no live workflow state, cached configuration, or active controller prompt request. Runtime is dominated by one directory creation plus one file write when a capture exists and O(1) otherwise. Side effects include directory creation and file creation only when a capture exists and the status is an error status.
|
|
796
950
|
* @param[in] errorCode {number} Failing provider response status, such as `400`.
|
|
797
951
|
* @return {boolean} `true` when the provider error payload file is written; otherwise `false`.
|
|
798
952
|
* @satisfies REQ-422, REQ-423, REQ-424, REQ-425
|
|
799
953
|
*/
|
|
800
|
-
export function flushCapturedPromptErrorPayload(
|
|
801
|
-
projectBase: string,
|
|
802
|
-
config: UseReqConfig,
|
|
803
|
-
workflowState: DebugWorkflowState,
|
|
804
|
-
promptName: PromptCommandName,
|
|
805
|
-
errorCode: number,
|
|
806
|
-
): boolean {
|
|
954
|
+
export function flushCapturedPromptErrorPayload(errorCode: number): boolean {
|
|
807
955
|
const captureStore = getProcessScopedPromptErrorCaptureStore();
|
|
808
956
|
const captured = captureStore.capturedPromptErrorPayload;
|
|
809
957
|
captureStore.capturedPromptErrorPayload = undefined;
|
|
810
|
-
if (!captured ||
|
|
958
|
+
if (!captured || !Number.isFinite(errorCode) || errorCode < 400) {
|
|
811
959
|
return false;
|
|
812
960
|
}
|
|
813
|
-
if (!shouldLogDebugPromptContent(config, workflowState, promptName)) {
|
|
814
|
-
return false;
|
|
815
|
-
}
|
|
816
|
-
const logDirectory = resolveDebugPromptsLogPath(projectBase, config);
|
|
817
961
|
try {
|
|
818
|
-
fs.mkdirSync(logDirectory, { recursive: true });
|
|
962
|
+
fs.mkdirSync(captured.logDirectory, { recursive: true });
|
|
819
963
|
fs.writeFileSync(
|
|
820
|
-
path.join(logDirectory, formatPromptDebugErrorFileName(promptName, errorCode)),
|
|
964
|
+
path.join(captured.logDirectory, formatPromptDebugErrorFileName(captured.promptName, errorCode)),
|
|
821
965
|
captured.payloadText,
|
|
822
966
|
"utf8",
|
|
823
967
|
);
|
|
@@ -826,3 +970,13 @@ export function flushCapturedPromptErrorPayload(
|
|
|
826
970
|
return false;
|
|
827
971
|
}
|
|
828
972
|
}
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* @brief Discards any captured provider request payload for the ended prompt run.
|
|
976
|
+
* @details Clears the process-scoped capture unconditionally so leftover payloads from a finished `req-*` prompt run never flush into later provider errors raised outside extension-owned prompt orchestration. Runtime is O(1). Side effect: mutates the process-scoped capture store.
|
|
977
|
+
* @return {void} No return value.
|
|
978
|
+
* @satisfies REQ-421, REQ-425
|
|
979
|
+
*/
|
|
980
|
+
export function discardCapturedPromptErrorPayload(): void {
|
|
981
|
+
getProcessScopedPromptErrorCaptureStore().capturedPromptErrorPayload = undefined;
|
|
982
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -134,9 +134,11 @@ import {
|
|
|
134
134
|
DEFAULT_DEBUG_TOOL_COMMANDS_ENABLED,
|
|
135
135
|
DEFAULT_DEBUG_WORKFLOW_EVENTS,
|
|
136
136
|
capturePromptProviderRequestForDebug,
|
|
137
|
+
discardCapturedPromptErrorPayload,
|
|
137
138
|
flushCapturedPromptErrorPayload,
|
|
138
139
|
logDebugPromptContent,
|
|
139
140
|
logDebugPromptEvent,
|
|
141
|
+
logDebugPromptRequest,
|
|
140
142
|
logDebugPromptWorkflowEvent,
|
|
141
143
|
logDebugToolExecution,
|
|
142
144
|
normalizeDebugEnabledPrompts,
|
|
@@ -148,6 +150,7 @@ import {
|
|
|
148
150
|
normalizeDebugStatusChanges,
|
|
149
151
|
normalizeDebugToolCommandsEnabled,
|
|
150
152
|
normalizeDebugWorkflowEvents,
|
|
153
|
+
setRuntimeDebugEnabled,
|
|
151
154
|
shouldLogDebugPromptWorkflowState,
|
|
152
155
|
type DebugLogOnStatus,
|
|
153
156
|
type DebugWorkflowState,
|
|
@@ -1445,14 +1448,14 @@ async function finalizeMatchedPromptSuccess(
|
|
|
1445
1448
|
|
|
1446
1449
|
/**
|
|
1447
1450
|
* @brief Handles one intercepted pi lifecycle hook for pi-usereq status updates.
|
|
1448
|
-
* @details Applies session-start-specific resource validation, project-config refresh, idle-time shared-tokenizer and context-file measurement pre-warm, startup-tool enablement, and selected debug-tool logging before forwarding the originating hook name and payload into the shared `updateExtensionStatus(...)` pipeline. Before `agent_start`, re-verifies any prepared prompt execution session switch. On `agent_end`, dispatches configured command-notify, sound, and prompt-specific Pushover effects, logs dedicated workflow-closure diagnostics, classifies the prompt outcome, and for every matched successful worktree-backed completion defers the restore switch, stash-assisted merge, and worktree deletion to `agent_settled` when the running pi host supports that 0.80.4+ event (because its `switchSession` awaits the active agent run to become idle and would deadlock inside `agent_end`), or executes the finalization directly at `agent_end` when the host does not emit `agent_settled`. On `agent_settled`, reuses persisted replacement-session command contexts when event contexts omit `switchSession()`, executes the deferred stash-assisted merge-and-delete finalization path, emits a warning-only notification when restored `base-path` changes are reapplied after merge, tolerates stale replacement-session notification contexts after session replacement, retains the worktree plus notifies closure failure for interrupted or failed outcomes, logs selected prompt workflow transitions, and transitions workflow state through `merging`, `error`, and `idle` as required. On `session_shutdown`, captures pre-update prompt snapshots so workflow-shutdown diagnostics and same-runtime command continuation preserve the active prompt workflow state across switch-triggered rebinding, then disposes the shared controller. Runtime is dominated by configuration loading during `session_start` and git finalization during matched successful closure handling; all other hooks are O(1). Side effects include resource checks, active-tool mutation, active-session replacement, status updates, live-ticker disposal on shutdown, optional child-process spawning, outbound HTTPS requests, branch merges, worktree deletion, and optional debug-log writes.
|
|
1451
|
+
* @details Applies session-start-specific resource validation, project-config refresh, idle-time shared-tokenizer and context-file measurement pre-warm, startup-tool enablement, and selected debug-tool logging before forwarding the originating hook name and payload into the shared `updateExtensionStatus(...)` pipeline. After the status update, captures the exact `before_provider_request` provider payload for the live active or pending prompt run with a fresh config fallback when the controller has no cached config, flushes the process-scoped captured payload as one `<timestamp>-<req-command>-error-<status>` file whenever `after_provider_response` reports a status >= 400 without requiring live workflow state, and discards the capture at prompt-run end so stale payloads never reach later runs. Before `agent_start`, re-verifies any prepared prompt execution session switch. On `agent_end`, dispatches configured command-notify, sound, and prompt-specific Pushover effects, logs dedicated workflow-closure diagnostics, classifies the prompt outcome, and for every matched successful worktree-backed completion defers the restore switch, stash-assisted merge, and worktree deletion to `agent_settled` when the running pi host supports that 0.80.4+ event (because its `switchSession` awaits the active agent run to become idle and would deadlock inside `agent_end`), or executes the finalization directly at `agent_end` when the host does not emit `agent_settled`. On `agent_settled`, reuses persisted replacement-session command contexts when event contexts omit `switchSession()`, executes the deferred stash-assisted merge-and-delete finalization path, emits a warning-only notification when restored `base-path` changes are reapplied after merge, tolerates stale replacement-session notification contexts after session replacement, retains the worktree plus notifies closure failure for interrupted or failed outcomes, logs selected prompt workflow transitions, and transitions workflow state through `merging`, `error`, and `idle` as required. On `session_shutdown`, captures pre-update prompt snapshots so workflow-shutdown diagnostics and same-runtime command continuation preserve the active prompt workflow state across switch-triggered rebinding, then disposes the shared controller. Runtime is dominated by configuration loading during `session_start` and git finalization during matched successful closure handling; all other hooks are O(1). Side effects include resource checks, active-tool mutation, active-session replacement, status updates, live-ticker disposal on shutdown, optional child-process spawning, outbound HTTPS requests, branch merges, worktree deletion, and optional debug-log writes.
|
|
1449
1452
|
* @param[in] pi {ExtensionAPI} Active extension API instance.
|
|
1450
1453
|
* @param[in,out] statusController {PiUsereqStatusController} Mutable status controller.
|
|
1451
1454
|
* @param[in] hookName {PiUsereqStatusHookName} Intercepted hook name.
|
|
1452
1455
|
* @param[in] event {unknown} Hook payload forwarded by pi.
|
|
1453
1456
|
* @param[in] ctx {ExtensionContext} Active extension context.
|
|
1454
1457
|
* @return {Promise<void>} Promise resolved when hook processing completes.
|
|
1455
|
-
* @satisfies REQ-117, REQ-118, REQ-119, REQ-131, REQ-132, REQ-133, REQ-166, REQ-167, REQ-168, REQ-169, REQ-172, REQ-176, REQ-178, REQ-184, REQ-185, REQ-186, REQ-187, REQ-208, REQ-209, REQ-221, REQ-228, REQ-229, REQ-230, REQ-244, REQ-245, REQ-246, REQ-247, REQ-276, REQ-277, REQ-278, REQ-279, REQ-280, REQ-291, REQ-292
|
|
1458
|
+
* @satisfies REQ-117, REQ-118, REQ-119, REQ-131, REQ-132, REQ-133, REQ-166, REQ-167, REQ-168, REQ-169, REQ-172, REQ-176, REQ-178, REQ-184, REQ-185, REQ-186, REQ-187, REQ-208, REQ-209, REQ-221, REQ-228, REQ-229, REQ-230, REQ-244, REQ-245, REQ-246, REQ-247, REQ-276, REQ-277, REQ-278, REQ-279, REQ-280, REQ-291, REQ-292, REQ-421, REQ-422, REQ-425
|
|
1456
1459
|
*/
|
|
1457
1460
|
async function handleExtensionStatusEvent(
|
|
1458
1461
|
pi: ExtensionAPI,
|
|
@@ -1511,27 +1514,31 @@ async function handleExtensionStatusEvent(
|
|
|
1511
1514
|
}
|
|
1512
1515
|
: undefined;
|
|
1513
1516
|
updateExtensionStatus(statusController, hookName, event, ctx);
|
|
1514
|
-
|
|
1517
|
+
// Provider payload capture and error flush read the LIVE post-update controller state and fall
|
|
1518
|
+
// back to a fresh config load: after switchSession rebinds the extension, the entry-read
|
|
1519
|
+
// `activePromptRequest` snapshot can be stale, `agent_start` promotion may lag one hook, and the
|
|
1520
|
+
// replacement-session instance may not have cached config yet. The process-scoped capture store
|
|
1521
|
+
// carries everything the error-stage write needs, so the flush itself is state-independent.
|
|
1522
|
+
const livePromptRequest = statusController.state.activePromptRequest
|
|
1523
|
+
?? statusController.state.pendingPromptRequest;
|
|
1524
|
+
if (hookName === "before_provider_request" && livePromptRequest !== undefined) {
|
|
1515
1525
|
const providerRequestEvent = event as { payload?: unknown };
|
|
1516
1526
|
capturePromptProviderRequestForDebug(
|
|
1517
|
-
statusController.config,
|
|
1518
|
-
|
|
1519
|
-
|
|
1527
|
+
statusController.config ?? loadProjectConfig(resolveLiveBootstrapCwd(ctx.cwd)),
|
|
1528
|
+
livePromptRequest.promptName,
|
|
1529
|
+
livePromptRequest.basePath,
|
|
1520
1530
|
providerRequestEvent.payload,
|
|
1521
1531
|
);
|
|
1522
1532
|
}
|
|
1523
|
-
if (hookName === "after_provider_response"
|
|
1533
|
+
if (hookName === "after_provider_response") {
|
|
1524
1534
|
const providerResponseEvent = event as { status?: unknown };
|
|
1525
1535
|
if (typeof providerResponseEvent.status === "number" && providerResponseEvent.status >= 400) {
|
|
1526
|
-
flushCapturedPromptErrorPayload(
|
|
1527
|
-
activePromptRequest.basePath,
|
|
1528
|
-
statusController.config,
|
|
1529
|
-
statusController.state.workflowState,
|
|
1530
|
-
activePromptRequest.promptName,
|
|
1531
|
-
providerResponseEvent.status,
|
|
1532
|
-
);
|
|
1536
|
+
flushCapturedPromptErrorPayload(providerResponseEvent.status);
|
|
1533
1537
|
}
|
|
1534
1538
|
}
|
|
1539
|
+
if (hookName === "agent_end" || hookName === "agent_settled") {
|
|
1540
|
+
discardCapturedPromptErrorPayload();
|
|
1541
|
+
}
|
|
1535
1542
|
if (hookName === "tool_result" && statusController.config) {
|
|
1536
1543
|
const toolEvent = event as {
|
|
1537
1544
|
toolName?: string;
|
|
@@ -1806,13 +1813,14 @@ function getDebugToolToggleNames(): PiUsereqStartupToolName[] {
|
|
|
1806
1813
|
|
|
1807
1814
|
/**
|
|
1808
1815
|
* @brief Restores the debug configuration subtree to its documented defaults.
|
|
1809
|
-
* @details Resets
|
|
1816
|
+
* @details Resets runtime debug enablement in both the effective config object and the process-scoped runtime debug store, then resets log path, prompt-content debug enablement plus prompt log path, tool-wrapper command registration, workflow-state filter, dedicated workflow-event logging, and selected tool plus prompt debug toggles without mutating unrelated settings. Runtime is O(1). Side effect: mutates `config` and process-scoped runtime debug state.
|
|
1810
1817
|
* @param[in,out] config {UseReqConfig} Mutable configuration object.
|
|
1811
1818
|
* @return {void} No return value.
|
|
1812
|
-
* @satisfies REQ-236, REQ-237, REQ-238, REQ-239, REQ-195, REQ-277, REQ-322, REQ-413, REQ-414, REQ-420
|
|
1819
|
+
* @satisfies REQ-236, REQ-237, REQ-238, REQ-239, REQ-195, REQ-277, REQ-322, REQ-413, REQ-414, REQ-420, REQ-426
|
|
1813
1820
|
*/
|
|
1814
1821
|
function resetDebugConfigToDefaults(config: UseReqConfig): void {
|
|
1815
1822
|
config.DEBUG_ENABLED = "disable";
|
|
1823
|
+
setRuntimeDebugEnabled("disable");
|
|
1816
1824
|
config.DEBUG_LOG_FILE = DEFAULT_DEBUG_LOG_FILE;
|
|
1817
1825
|
config.DEBUG_PROMPTS_ENABLED = DEFAULT_DEBUG_PROMPTS_ENABLED;
|
|
1818
1826
|
config.DEBUG_PROMPTS_LOG_PATH = DEFAULT_DEBUG_PROMPTS_LOG_PATH;
|
|
@@ -2014,12 +2022,12 @@ function buildDebugMenuChoices(config: UseReqConfig): PiUsereqSettingsMenuChoice
|
|
|
2014
2022
|
|
|
2015
2023
|
/**
|
|
2016
2024
|
* @brief Runs the interactive Debug submenu.
|
|
2017
|
-
* @details Lets the user toggle global debug enablement, prompt-content debug enablement plus prompt log path, tool-wrapper command registration, debug file and workflow filters, dedicated workflow-event logging, per-tool selectors, and per-prompt selectors while preserving row focus across re-renders. Runtime depends on user interaction count. Side effects include UI updates, config mutation, and optional debug command registration.
|
|
2025
|
+
* @details Lets the user toggle runtime global debug enablement (stored only in the process-scoped runtime debug store and never persisted), prompt-content debug enablement plus prompt log path, tool-wrapper command registration, debug file and workflow filters, dedicated workflow-event logging, per-tool selectors, and per-prompt selectors while preserving row focus across re-renders. Runtime depends on user interaction count. Side effects include UI updates, config mutation, process-scoped runtime debug state mutation, and optional debug command registration.
|
|
2018
2026
|
* @param[in] pi {ExtensionAPI} Active extension API instance.
|
|
2019
2027
|
* @param[in] ctx {ExtensionCommandContext} Active command context.
|
|
2020
2028
|
* @param[in,out] config {UseReqConfig} Mutable configuration object.
|
|
2021
2029
|
* @return {Promise<void>} Promise resolved when the submenu closes.
|
|
2022
|
-
* @satisfies REQ-236, REQ-237, REQ-238, REQ-239, REQ-240, REQ-241, REQ-242, REQ-243, REQ-192, REQ-193, REQ-195, REQ-277, REQ-321, REQ-322, REQ-323, REQ-413, REQ-414, REQ-415, REQ-420
|
|
2030
|
+
* @satisfies REQ-236, REQ-237, REQ-238, REQ-239, REQ-240, REQ-241, REQ-242, REQ-243, REQ-192, REQ-193, REQ-195, REQ-277, REQ-321, REQ-322, REQ-323, REQ-413, REQ-414, REQ-415, REQ-420, REQ-426
|
|
2023
2031
|
*/
|
|
2024
2032
|
async function configureDebugMenu(
|
|
2025
2033
|
pi: ExtensionAPI,
|
|
@@ -2044,6 +2052,7 @@ async function configureDebugMenu(
|
|
|
2044
2052
|
onChange: (choiceId, newValue) => {
|
|
2045
2053
|
if (choiceId === "debug-enabled") {
|
|
2046
2054
|
config.DEBUG_ENABLED = newValue === "enable" ? "enable" : "disable";
|
|
2055
|
+
setRuntimeDebugEnabled(config.DEBUG_ENABLED);
|
|
2047
2056
|
onConfigChange();
|
|
2048
2057
|
ctx.ui.notify(`Debug ${config.DEBUG_ENABLED}`, "info");
|
|
2049
2058
|
return;
|
|
@@ -2110,6 +2119,7 @@ async function configureDebugMenu(
|
|
|
2110
2119
|
|
|
2111
2120
|
if (choice === "debug-enabled") {
|
|
2112
2121
|
config.DEBUG_ENABLED = config.DEBUG_ENABLED === "enable" ? "disable" : "enable";
|
|
2122
|
+
setRuntimeDebugEnabled(config.DEBUG_ENABLED);
|
|
2113
2123
|
onConfigChange();
|
|
2114
2124
|
ctx.ui.notify(`Debug ${config.DEBUG_ENABLED}`, "info");
|
|
2115
2125
|
continue;
|
|
@@ -3453,11 +3463,11 @@ function registerReqReferencesCommand(
|
|
|
3453
3463
|
|
|
3454
3464
|
/**
|
|
3455
3465
|
* @brief Registers bundled prompt-backed commands with the extension.
|
|
3456
|
-
* @details Creates one prompt-template-backed `req-<prompt>` command per bundled prompt name. Each handler rejects non-`idle` workflow state by transitioning the shared workflow state to `error` before command-side preflight, otherwise transitions the shared workflow state through `checking`, `error`, and `running`, runs dedicated prompt-command git and required-doc preflight checks, optionally prepares a dedicated worktree execution plan using the active session directory, persists the prompt metadata needed for switch-triggered rebinding, switches the active session to the verified execution cwd before prompt handoff, logs dedicated workflow-activation diagnostics, renders the prompt, starts prompt delivery into the forked active session, records `running` immediately after delivery handoff begins, saves the exact delivered prompt content into the debug prompt log path when prompt debug logging is enabled, and then awaits the wrapped prompt-delivery promise whose stale post-restore rejections are suppressed. Runtime is O(p) for registration; handler cost depends on prompt preflight, worktree preparation, session switching, prompt rendering, prompt dispatch, and optional debug logging. Side effects include command registration, status-controller mutation, worktree creation, active-session replacement, optional worktree rollback, optional prompt-
|
|
3466
|
+
* @details Creates one prompt-template-backed `req-<prompt>` command per bundled prompt name. Each handler rejects non-`idle` workflow state by transitioning the shared workflow state to `error` before command-side preflight, otherwise transitions the shared workflow state through `checking`, `error`, and `running`, runs dedicated prompt-command git and required-doc preflight checks, optionally prepares a dedicated worktree execution plan using the active session directory, persists the prompt metadata needed for switch-triggered rebinding, switches the active session to the verified execution cwd before prompt handoff, logs dedicated workflow-activation diagnostics, renders the prompt, starts prompt delivery into the forked active session, records `running` immediately after delivery handoff begins, saves the exact command invocation summary plus the delivered prompt content into the debug prompt log path as separate `-request` and `-prompt` files when prompt debug logging is enabled, and then awaits the wrapped prompt-delivery promise whose stale post-restore rejections are suppressed. Runtime is O(p) for registration; handler cost depends on prompt preflight, worktree preparation, session switching, prompt rendering, prompt dispatch, and optional debug logging. Side effects include command registration, status-controller mutation, worktree creation, active-session replacement, optional worktree rollback, optional prompt-debug file creation, user-message delivery during execution, and optional debug-log writes.
|
|
3457
3467
|
* @param[in] pi {ExtensionAPI} Active extension API instance.
|
|
3458
3468
|
* @param[in,out] statusController {PiUsereqStatusController} Mutable status controller.
|
|
3459
3469
|
* @return {void} No return value.
|
|
3460
|
-
* @satisfies REQ-004, REQ-067, REQ-068, REQ-169, REQ-200, REQ-201, REQ-202, REQ-203, REQ-206, REQ-207, REQ-219, REQ-220, REQ-221, REQ-224, REQ-225, REQ-226, REQ-227, REQ-245, REQ-246, REQ-247, REQ-277, REQ-281, REQ-377, REQ-416, REQ-417, REQ-418
|
|
3470
|
+
* @satisfies REQ-004, REQ-067, REQ-068, REQ-169, REQ-200, REQ-201, REQ-202, REQ-203, REQ-206, REQ-207, REQ-219, REQ-220, REQ-221, REQ-224, REQ-225, REQ-226, REQ-227, REQ-245, REQ-246, REQ-247, REQ-277, REQ-281, REQ-377, REQ-416, REQ-417, REQ-418, REQ-427, REQ-428
|
|
3461
3471
|
*/
|
|
3462
3472
|
function registerPromptCommands(
|
|
3463
3473
|
pi: ExtensionAPI,
|
|
@@ -3563,6 +3573,13 @@ function registerPromptCommands(
|
|
|
3563
3573
|
promptName,
|
|
3564
3574
|
"running",
|
|
3565
3575
|
);
|
|
3576
|
+
logDebugPromptRequest(
|
|
3577
|
+
projectBase,
|
|
3578
|
+
config,
|
|
3579
|
+
statusController.state.workflowState,
|
|
3580
|
+
promptName,
|
|
3581
|
+
commandSummary,
|
|
3582
|
+
);
|
|
3566
3583
|
logDebugPromptContent(
|
|
3567
3584
|
projectBase,
|
|
3568
3585
|
config,
|