pi-usereq 0.11.0 → 0.13.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 +59 -0
- package/README.md +6 -6
- package/package.json +1 -1
- package/pi-usereq/docs/REFERENCES.md +1135 -834
- package/pi-usereq/docs/REQUIREMENTS.md +177 -110
- package/pi-usereq/docs/WORKFLOW.md +244 -79
- 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/config.ts +541 -180
- package/src/core/extension-status.ts +69 -12
- package/src/core/path-context.ts +19 -4
- 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 +183 -44
- 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/settings-menu.ts +85 -28
- package/src/core/tool-runner.ts +26 -6
- package/src/index.ts +601 -116
- package/tests/attended-results-scenarios.ts +15 -9
- package/tests/cli-command-option-parity.test.ts +53 -35
- package/tests/debug-extension-harness.test.ts +8 -10
- package/tests/extension-registration.test.ts +1204 -205
- package/tests/helpers.ts +29 -6
- 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
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ThemeColor,
|
|
15
15
|
} from "@mariozechner/pi-coding-agent";
|
|
16
16
|
import type { UseReqConfig } from "./config.js";
|
|
17
|
+
import type { PiNotifySoundLevel } from "./pi-notify.js";
|
|
17
18
|
import type { PromptCommandExecutionPlan } from "./prompt-command-runtime.js";
|
|
18
19
|
import {
|
|
19
20
|
restorePersistedPromptCommandRuntimeStateForSession,
|
|
@@ -111,7 +112,7 @@ export type PiUsereqWorkflowState = "idle" | "checking" | "running" | "merging"
|
|
|
111
112
|
|
|
112
113
|
/**
|
|
113
114
|
* @brief Stores the mutable runtime facts displayed by the status bar.
|
|
114
|
-
* @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.
|
|
115
116
|
*/
|
|
116
117
|
export interface PiUsereqStatusState {
|
|
117
118
|
workflowState: PiUsereqWorkflowState;
|
|
@@ -119,6 +120,7 @@ export interface PiUsereqStatusState {
|
|
|
119
120
|
runStartTimeMs: number | undefined;
|
|
120
121
|
lastRunDurationMs: number | undefined;
|
|
121
122
|
totalRunDurationMs: number | undefined;
|
|
123
|
+
runtimeSoundLevel: PiNotifySoundLevel | undefined;
|
|
122
124
|
pendingPromptRequest: PiUsereqPromptRequest | undefined;
|
|
123
125
|
activePromptRequest: PiUsereqPromptRequest | undefined;
|
|
124
126
|
}
|
|
@@ -403,7 +405,7 @@ function resolveContextUsageIconText(
|
|
|
403
405
|
|
|
404
406
|
/**
|
|
405
407
|
* @brief Formats one icon-based context-usage gauge.
|
|
406
|
-
* @details Renders the documented gauge icon with theme `
|
|
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.
|
|
407
409
|
* @param[in] theme {StatusThemeAdapter} Normalized status theme.
|
|
408
410
|
* @param[in] contextUsage {ContextUsage | undefined} Normalized context snapshot.
|
|
409
411
|
* @return {string} Rendered fixed-width gauge icon.
|
|
@@ -420,7 +422,7 @@ function formatContextUsageBar(
|
|
|
420
422
|
if (percent >= 90) {
|
|
421
423
|
return theme.colorize("error", "▕█▏");
|
|
422
424
|
}
|
|
423
|
-
return resolveContextUsageIconText(contextUsage);
|
|
425
|
+
return theme.value(resolveContextUsageIconText(contextUsage));
|
|
424
426
|
}
|
|
425
427
|
|
|
426
428
|
/**
|
|
@@ -548,9 +550,24 @@ function didAgentEndAbort(messages: AgentEndEvent["messages"]): boolean {
|
|
|
548
550
|
);
|
|
549
551
|
}
|
|
550
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
|
+
|
|
551
568
|
/**
|
|
552
569
|
* @brief Builds the full single-line pi-usereq status-bar payload.
|
|
553
|
-
* @details Renders status, branch, context, elapsed, and sound fields in the canonical order with dim bullet separators, workflow-state highlighting,
|
|
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.
|
|
554
571
|
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
555
572
|
* @param[in] theme {StatusThemeAdapter} Normalized status theme.
|
|
556
573
|
* @param[in] state {PiUsereqStatusState} Mutable status state snapshot.
|
|
@@ -567,7 +584,7 @@ function buildPiUsereqStatusText(
|
|
|
567
584
|
nowMs: number,
|
|
568
585
|
): string {
|
|
569
586
|
const elapsedText = formatElapsedStatusValue(state, nowMs);
|
|
570
|
-
const soundText = config
|
|
587
|
+
const soundText = resolvePiUsereqRuntimeSoundLevel(state, config);
|
|
571
588
|
return [
|
|
572
589
|
formatRenderedStatusField(
|
|
573
590
|
theme,
|
|
@@ -630,7 +647,7 @@ function syncPiUsereqStatusTicker(
|
|
|
630
647
|
|
|
631
648
|
/**
|
|
632
649
|
* @brief Creates an empty pi-usereq status controller.
|
|
633
|
-
* @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.
|
|
634
651
|
* @return {PiUsereqStatusController} New status controller.
|
|
635
652
|
* @satisfies DES-010
|
|
636
653
|
*/
|
|
@@ -644,6 +661,7 @@ export function createPiUsereqStatusController(): PiUsereqStatusController {
|
|
|
644
661
|
runStartTimeMs: undefined,
|
|
645
662
|
lastRunDurationMs: undefined,
|
|
646
663
|
totalRunDurationMs: undefined,
|
|
664
|
+
runtimeSoundLevel: undefined,
|
|
647
665
|
pendingPromptRequest: undefined,
|
|
648
666
|
activePromptRequest: undefined,
|
|
649
667
|
},
|
|
@@ -654,8 +672,9 @@ export function createPiUsereqStatusController(): PiUsereqStatusController {
|
|
|
654
672
|
/**
|
|
655
673
|
* @brief Stores the effective project configuration used by status rendering.
|
|
656
674
|
* @details Replaces the controller's cached configuration so later status
|
|
657
|
-
* renders reuse the latest docs, tests, source-path, and pi-notify
|
|
658
|
-
* 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:
|
|
659
678
|
* mutates `controller.config`.
|
|
660
679
|
* @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
|
|
661
680
|
* @param[in] config {UseReqConfig} Effective project configuration.
|
|
@@ -668,13 +687,47 @@ export function setPiUsereqStatusConfig(
|
|
|
668
687
|
controller.config = config;
|
|
669
688
|
}
|
|
670
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 global configuration. 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 persisted local or global configuration, 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
|
+
|
|
671
724
|
/**
|
|
672
725
|
* @brief Renders the current pi-usereq status bar into the active UI context.
|
|
673
|
-
* @details Updates the controller's latest context pointer and writes the single-line status text only when configuration is available, including the active branch field
|
|
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.
|
|
674
727
|
* @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
|
|
675
728
|
* @param[in] ctx {ExtensionContext} Active extension context.
|
|
676
729
|
* @return {void} No return value.
|
|
677
|
-
* @satisfies 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
|
|
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
|
|
678
731
|
*/
|
|
679
732
|
export function renderPiUsereqStatus(
|
|
680
733
|
controller: PiUsereqStatusController,
|
|
@@ -685,6 +738,7 @@ export function renderPiUsereqStatus(
|
|
|
685
738
|
return;
|
|
686
739
|
}
|
|
687
740
|
try {
|
|
741
|
+
refreshContextUsage(controller.state, ctx);
|
|
688
742
|
const theme = createStatusThemeAdapter(ctx.ui.theme as RawStatusTheme);
|
|
689
743
|
const branchName = resolveStatusBranchValue(ctx);
|
|
690
744
|
ctx.ui.setStatus(
|
|
@@ -732,13 +786,13 @@ export function setPiUsereqWorkflowState(
|
|
|
732
786
|
|
|
733
787
|
/**
|
|
734
788
|
* @brief Updates mutable status state for one intercepted lifecycle hook.
|
|
735
|
-
* @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.
|
|
736
790
|
* @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
|
|
737
791
|
* @param[in] hookName {PiUsereqStatusHookName} Intercepted hook name.
|
|
738
792
|
* @param[in] event {unknown} Hook payload forwarded from the wrapper.
|
|
739
793
|
* @param[in] ctx {ExtensionContext} Active extension context.
|
|
740
794
|
* @return {void} No return value.
|
|
741
|
-
* @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
|
|
742
796
|
*/
|
|
743
797
|
export function updateExtensionStatus(
|
|
744
798
|
controller: PiUsereqStatusController,
|
|
@@ -757,6 +811,9 @@ export function updateExtensionStatus(
|
|
|
757
811
|
} else {
|
|
758
812
|
restorePersistedElapsedState(controller.state);
|
|
759
813
|
}
|
|
814
|
+
controller.state.runtimeSoundLevel = controller.config?.["notify-sound"]
|
|
815
|
+
?? controller.state.runtimeSoundLevel
|
|
816
|
+
?? "none";
|
|
760
817
|
const shouldResetWorkflowState = shouldResetWorkflowStateOnSessionStart(event);
|
|
761
818
|
if (shouldResetWorkflowState) {
|
|
762
819
|
controller.state.workflowState = "idle";
|
package/src/core/path-context.ts
CHANGED
|
@@ -11,11 +11,17 @@ import { fileURLToPath } from "node:url";
|
|
|
11
11
|
import type { UseReqConfig } from "./config.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* @brief Defines the per-project configuration file name.
|
|
15
|
-
* @details The file lives directly under `base-path` and stores only persisted project configuration. Access complexity is O(1).
|
|
14
|
+
* @brief Defines the per-project local configuration file name.
|
|
15
|
+
* @details The file lives directly under `base-path` and stores only persisted project-scoped configuration. Access complexity is O(1).
|
|
16
16
|
*/
|
|
17
17
|
export const PROJECT_CONFIG_FILENAME = ".pi-usereq.json";
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @brief Defines the home-relative global configuration file path.
|
|
21
|
+
* @details The path is resolved against the current user home directory and stores persisted cross-project configuration. Access complexity is O(1).
|
|
22
|
+
*/
|
|
23
|
+
export const GLOBAL_CONFIG_RELATIVE_PATH = ".config/pi-usereq/config.json";
|
|
24
|
+
|
|
19
25
|
/**
|
|
20
26
|
* @brief Defines the bundled resources directory name under the installation path.
|
|
21
27
|
* @details The directory contains prompts, templates, and guidelines shipped with the installed extension payload. Access complexity is O(1).
|
|
@@ -155,15 +161,24 @@ export function normalizeRelativeDirContract(value: string): string {
|
|
|
155
161
|
}
|
|
156
162
|
|
|
157
163
|
/**
|
|
158
|
-
* @brief Computes the absolute project config path for one base path.
|
|
164
|
+
* @brief Computes the absolute local project config path for one base path.
|
|
159
165
|
* @details Appends `.pi-usereq.json` to the supplied base path using the canonical repository-local configuration layout. Runtime is O(1). No external state is mutated.
|
|
160
166
|
* @param[in] basePath {string} Absolute or relative base path.
|
|
161
|
-
* @return {string} Absolute config-file path.
|
|
167
|
+
* @return {string} Absolute local config-file path.
|
|
162
168
|
*/
|
|
163
169
|
export function getConfigPath(basePath: string): string {
|
|
164
170
|
return path.join(path.resolve(basePath), PROJECT_CONFIG_FILENAME);
|
|
165
171
|
}
|
|
166
172
|
|
|
173
|
+
/**
|
|
174
|
+
* @brief Computes the absolute global config path for the current user.
|
|
175
|
+
* @details Resolves `~/.config/pi-usereq/config.json` from the current user home directory without consulting project state. Runtime is O(1). No external state is mutated.
|
|
176
|
+
* @return {string} Absolute global config-file path.
|
|
177
|
+
*/
|
|
178
|
+
export function getGlobalConfigPath(): string {
|
|
179
|
+
return path.join(os.homedir(), GLOBAL_CONFIG_RELATIVE_PATH);
|
|
180
|
+
}
|
|
181
|
+
|
|
167
182
|
/**
|
|
168
183
|
* @brief Tests whether one path is identical to or an ancestor of another path.
|
|
169
184
|
* @details Resolves both inputs, computes a relative traversal from the candidate ancestor to the candidate child, and accepts only exact matches or descendant traversals that stay within the ancestor subtree. Runtime is O(p) in path length. No external state is mutated.
|
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",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file
|
|
3
|
-
* @brief Implements prompt-command preflight and worktree orchestration.
|
|
4
|
-
* @details Centralizes `req-<prompt>` repository validation, prompt-specific required-document checks, slash-command-owned worktree naming and lifecycle handling,
|
|
3
|
+
* @brief Implements bundled prompt-command preflight and worktree orchestration.
|
|
4
|
+
* @details Centralizes prompt-template-backed `req-<prompt>` repository validation, prompt-specific required-document checks, slash-command-owned worktree naming and lifecycle handling, reusable transcript-preservation plus session-restoration helpers, persisted replacement-session context reuse for non-command lifecycle handlers, matched-success stash-assisted fast-forward merge finalization, and command-side abort cleanup. Runtime is dominated by git subprocess execution plus bounded filesystem and session-file metadata checks. Side effects include active-session replacement, worktree creation and deletion, branch merges, stash-stack mutation, and filesystem reads and writes.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import fs from "node:fs";
|
|
@@ -19,10 +19,7 @@ import {
|
|
|
19
19
|
logDebugPromptWorkflowEvent,
|
|
20
20
|
type DebugWorkflowState,
|
|
21
21
|
} from "./debug-runtime.js";
|
|
22
|
-
import {
|
|
23
|
-
PROMPT_COMMAND_NAMES,
|
|
24
|
-
type PromptCommandName,
|
|
25
|
-
} from "./prompt-command-catalog.js";
|
|
22
|
+
import { type PromptCommandName } from "./prompt-command-catalog.js";
|
|
26
23
|
import {
|
|
27
24
|
isSameOrAncestorPath,
|
|
28
25
|
normalizeRelativeDirContract,
|
|
@@ -483,9 +480,9 @@ function readPromptSessionJsonLines(
|
|
|
483
480
|
* @param[in] plan {PromptCommandExecutionPlan} Prompt execution plan whose original and execution session files must be synchronized.
|
|
484
481
|
* @return {void} No return value.
|
|
485
482
|
* @throws {ReqError} Throws when either session file is unreadable or when appended execution records are not persisted to the original session file.
|
|
486
|
-
* @satisfies REQ-208
|
|
483
|
+
* @satisfies REQ-208, REQ-307
|
|
487
484
|
*/
|
|
488
|
-
function preservePromptCommandExecutionTranscript(plan: PromptCommandExecutionPlan): void {
|
|
485
|
+
export function preservePromptCommandExecutionTranscript(plan: PromptCommandExecutionPlan): void {
|
|
489
486
|
const normalizedOriginalSessionFile = path.resolve(plan.originalSessionFile);
|
|
490
487
|
const normalizedExecutionSessionFile = path.resolve(plan.executionSessionFile);
|
|
491
488
|
if (normalizedOriginalSessionFile === normalizedExecutionSessionFile) {
|
|
@@ -829,9 +826,6 @@ const PROMPT_REQUIRED_DOCS: Record<PromptCommandName, readonly PromptRequiredDoc
|
|
|
829
826
|
{ fileName: "WORKFLOW.md", promptCommand: "/req-workflow" },
|
|
830
827
|
{ fileName: "REFERENCES.md", promptCommand: "/req-references" },
|
|
831
828
|
],
|
|
832
|
-
references: [
|
|
833
|
-
{ fileName: "REQUIREMENTS.md", promptCommand: "/req-write" },
|
|
834
|
-
],
|
|
835
829
|
renumber: [
|
|
836
830
|
{ fileName: "REQUIREMENTS.md", promptCommand: "/req-write" },
|
|
837
831
|
{ fileName: "WORKFLOW.md", promptCommand: "/req-workflow" },
|
|
@@ -855,6 +849,166 @@ function runCapture(command: string[], cwd: string): ReturnType<typeof spawnSync
|
|
|
855
849
|
});
|
|
856
850
|
}
|
|
857
851
|
|
|
852
|
+
/**
|
|
853
|
+
* @brief Lists tracked `base-path` status rows that require stash-assisted merge handling.
|
|
854
|
+
* @details Executes `git status --porcelain`, retains only tracked rows whose index or worktree slot reports a change, and excludes untracked or ignored rows because the required `git stash` command does not preserve them. Runtime is dominated by one git subprocess plus O(n) parsing in status-line count. Side effects include process spawning.
|
|
855
|
+
* @param[in] basePath {string} Restored project base path.
|
|
856
|
+
* @return {string[]} Tracked status rows requiring stash-assisted merge handling.
|
|
857
|
+
* @throws {ReqError} Throws when git status cannot be read from `basePath`.
|
|
858
|
+
* @satisfies REQ-291
|
|
859
|
+
*/
|
|
860
|
+
function listPromptTrackedBasePathChanges(basePath: string): string[] {
|
|
861
|
+
const statusResult = runCapture(["git", "status", "--porcelain"], basePath);
|
|
862
|
+
if (statusResult.error || statusResult.status !== 0) {
|
|
863
|
+
throw new ReqError("ERROR: Unable to inspect base-path changes before merge.", 1);
|
|
864
|
+
}
|
|
865
|
+
return statusResult.stdout
|
|
866
|
+
.split(/\r?\n/)
|
|
867
|
+
.map((line) => line.trimEnd())
|
|
868
|
+
.filter((line) => line !== "")
|
|
869
|
+
.filter((line) => {
|
|
870
|
+
const statusCode = line.slice(0, 2);
|
|
871
|
+
if (statusCode === "??" || statusCode === "!!") {
|
|
872
|
+
return false;
|
|
873
|
+
}
|
|
874
|
+
const indexStatus = statusCode[0] ?? " ";
|
|
875
|
+
const worktreeStatus = statusCode[1] ?? " ";
|
|
876
|
+
return indexStatus !== " " || worktreeStatus !== " ";
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* @brief Executes the successful-closure merge sequence from restored `base-path`.
|
|
882
|
+
* @details Detects tracked staged or unstaged `base-path` changes, wraps the existing fast-forward merge in `git stash` and `git stash pop` when required, preserves the direct merge path when no tracked changes exist, emits a warning-only result after successful local-change restoration, and writes one merge-finalization debug entry when enabled. Runtime is dominated by up to four git subprocesses plus O(n) status parsing. Side effects include stash-stack mutation, branch merge attempts, and optional debug-log writes.
|
|
883
|
+
* @param[in] plan {PromptCommandExecutionPlan} Prompt execution plan whose branch should be merged.
|
|
884
|
+
* @param[in] debugOptions {PromptCommandDebugOptions | undefined} Optional prompt debug logging context.
|
|
885
|
+
* @return {{ mergeAttempted: boolean; mergeSucceeded: boolean; errorMessage?: string; warningMessage?: string }} Merge-attempt facts plus optional warning text.
|
|
886
|
+
* @satisfies REQ-208, REQ-245, REQ-291, REQ-292
|
|
887
|
+
*/
|
|
888
|
+
function finalizePromptCommandMerge(
|
|
889
|
+
plan: PromptCommandExecutionPlan,
|
|
890
|
+
debugOptions?: PromptCommandDebugOptions,
|
|
891
|
+
): {
|
|
892
|
+
mergeAttempted: boolean;
|
|
893
|
+
mergeSucceeded: boolean;
|
|
894
|
+
errorMessage?: string;
|
|
895
|
+
warningMessage?: string;
|
|
896
|
+
} {
|
|
897
|
+
const worktreeDir = plan.worktreeDir ?? plan.branchName;
|
|
898
|
+
const mergeLogInput = {
|
|
899
|
+
worktree_dir: worktreeDir,
|
|
900
|
+
branch_name: plan.branchName,
|
|
901
|
+
};
|
|
902
|
+
let trackedStatusLines: string[];
|
|
903
|
+
try {
|
|
904
|
+
trackedStatusLines = listPromptTrackedBasePathChanges(plan.basePath);
|
|
905
|
+
} catch (error) {
|
|
906
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
907
|
+
if (debugOptions) {
|
|
908
|
+
logDebugPromptEvent(
|
|
909
|
+
plan.basePath,
|
|
910
|
+
debugOptions.config,
|
|
911
|
+
debugOptions.workflowState,
|
|
912
|
+
plan.promptName,
|
|
913
|
+
"merge",
|
|
914
|
+
mergeLogInput,
|
|
915
|
+
{
|
|
916
|
+
success: false,
|
|
917
|
+
merge_attempted: false,
|
|
918
|
+
error: errorMessage,
|
|
919
|
+
},
|
|
920
|
+
true,
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
return {
|
|
924
|
+
mergeAttempted: false,
|
|
925
|
+
mergeSucceeded: false,
|
|
926
|
+
errorMessage,
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
const usedStash = trackedStatusLines.length > 0;
|
|
930
|
+
let stashStatus: number | null | undefined;
|
|
931
|
+
if (usedStash) {
|
|
932
|
+
const stashResult = runCapture(["git", "stash"], plan.basePath);
|
|
933
|
+
stashStatus = stashResult.status;
|
|
934
|
+
if (stashResult.error || stashResult.status !== 0) {
|
|
935
|
+
const errorMessage = `ERROR: Unable to stash base-path changes before merge for worktree ${worktreeDir}.`;
|
|
936
|
+
if (debugOptions) {
|
|
937
|
+
logDebugPromptEvent(
|
|
938
|
+
plan.basePath,
|
|
939
|
+
debugOptions.config,
|
|
940
|
+
debugOptions.workflowState,
|
|
941
|
+
plan.promptName,
|
|
942
|
+
"merge",
|
|
943
|
+
{
|
|
944
|
+
...mergeLogInput,
|
|
945
|
+
used_stash: true,
|
|
946
|
+
tracked_change_count: trackedStatusLines.length,
|
|
947
|
+
},
|
|
948
|
+
{
|
|
949
|
+
success: false,
|
|
950
|
+
merge_attempted: false,
|
|
951
|
+
error: errorMessage,
|
|
952
|
+
stash_status: stashStatus,
|
|
953
|
+
},
|
|
954
|
+
true,
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
return {
|
|
958
|
+
mergeAttempted: false,
|
|
959
|
+
mergeSucceeded: false,
|
|
960
|
+
errorMessage,
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
const mergeResult = runCapture(
|
|
965
|
+
["git", "merge", "--ff-only", plan.branchName],
|
|
966
|
+
plan.basePath,
|
|
967
|
+
);
|
|
968
|
+
const mergeSucceeded = !mergeResult.error && mergeResult.status === 0;
|
|
969
|
+
const errorMessage = mergeSucceeded
|
|
970
|
+
? undefined
|
|
971
|
+
: `ERROR: Fast-forward merge failed for worktree ${worktreeDir}.`;
|
|
972
|
+
let stashPopStatus: number | null | undefined;
|
|
973
|
+
let warningMessage: string | undefined;
|
|
974
|
+
if (usedStash) {
|
|
975
|
+
const stashPopResult = runCapture(["git", "stash", "pop"], plan.basePath);
|
|
976
|
+
stashPopStatus = stashPopResult.status;
|
|
977
|
+
if (mergeSucceeded) {
|
|
978
|
+
warningMessage = "WARNING: Restored base-path changes after merge; base-path is not clean.";
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
if (debugOptions) {
|
|
982
|
+
logDebugPromptEvent(
|
|
983
|
+
plan.basePath,
|
|
984
|
+
debugOptions.config,
|
|
985
|
+
debugOptions.workflowState,
|
|
986
|
+
plan.promptName,
|
|
987
|
+
"merge",
|
|
988
|
+
{
|
|
989
|
+
...mergeLogInput,
|
|
990
|
+
used_stash: usedStash,
|
|
991
|
+
tracked_change_count: trackedStatusLines.length,
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
success: mergeSucceeded,
|
|
995
|
+
merge_attempted: true,
|
|
996
|
+
error: errorMessage,
|
|
997
|
+
warning: warningMessage,
|
|
998
|
+
stash_status: stashStatus,
|
|
999
|
+
stash_pop_status: stashPopStatus,
|
|
1000
|
+
},
|
|
1001
|
+
!mergeSucceeded,
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
return {
|
|
1005
|
+
mergeAttempted: true,
|
|
1006
|
+
mergeSucceeded,
|
|
1007
|
+
errorMessage,
|
|
1008
|
+
warningMessage,
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
|
|
858
1012
|
/**
|
|
859
1013
|
* @brief Stores or clears the prompt-command post-create test hook.
|
|
860
1014
|
* @details Enables deterministic simulation of post-create worktree verification failures without altering production control flow. Runtime is O(1). Side effect: mutates module-local test state.
|
|
@@ -950,15 +1104,15 @@ function throwPromptGitStatusError(): never {
|
|
|
950
1104
|
}
|
|
951
1105
|
|
|
952
1106
|
/**
|
|
953
|
-
* @brief Runs
|
|
954
|
-
* @details Validates work-tree membership, porcelain cleanliness, and symbolic or detached `HEAD` presence without invoking extension custom-tool executors. Runtime is dominated by git subprocess execution. Side effects include process spawning.
|
|
1107
|
+
* @brief Runs slash-command-owned git validation and returns the runtime git root.
|
|
1108
|
+
* @details Validates work-tree membership, porcelain cleanliness, and symbolic or detached `HEAD` presence for bundled prompt commands and `req-references` without invoking extension custom-tool executors. Runtime is dominated by git subprocess execution. Side effects include process spawning.
|
|
955
1109
|
* @param[in] projectBase {string} Absolute current project base.
|
|
956
1110
|
* @param[in] config {UseReqConfig | undefined} Optional effective project configuration used to ignore extension-owned debug-log artifacts.
|
|
957
1111
|
* @return {string} Absolute runtime git root.
|
|
958
1112
|
* @throws {ReqError} Throws the canonical prompt-command git-preflight error on any validation failure.
|
|
959
1113
|
* @satisfies REQ-200, REQ-220
|
|
960
1114
|
*/
|
|
961
|
-
function validatePromptGitState(projectBase: string, config?: UseReqConfig): string {
|
|
1115
|
+
export function validatePromptGitState(projectBase: string, config?: UseReqConfig): string {
|
|
962
1116
|
const gitPath = resolveRuntimeGitPath(projectBase);
|
|
963
1117
|
if (!gitPath) {
|
|
964
1118
|
throwPromptGitStatusError();
|
|
@@ -1280,9 +1434,9 @@ function createPromptWorktree(
|
|
|
1280
1434
|
* @param[in] debugOptions {PromptCommandDebugOptions | undefined} Optional prompt debug logging context.
|
|
1281
1435
|
* @return {void} No return value.
|
|
1282
1436
|
* @throws {ReqError} Throws when cleanup cannot remove the worktree and branch fully.
|
|
1283
|
-
* @satisfies REQ-208, REQ-220, REQ-245
|
|
1437
|
+
* @satisfies REQ-208, REQ-220, REQ-245, REQ-309
|
|
1284
1438
|
*/
|
|
1285
|
-
function deletePromptWorktree(
|
|
1439
|
+
export function deletePromptWorktree(
|
|
1286
1440
|
basePath: string,
|
|
1287
1441
|
worktreeDir: string,
|
|
1288
1442
|
worktreeRootPath: string,
|
|
@@ -1691,12 +1845,12 @@ export async function abortPromptCommandExecution(
|
|
|
1691
1845
|
|
|
1692
1846
|
/**
|
|
1693
1847
|
* @brief Finalizes one matched successful worktree-backed prompt execution.
|
|
1694
|
-
* @details Re-verifies persisted execution-session metadata plus worktree artifacts, copies any execution-session transcript records missing from the original session file, restores the original session-backed `base-path`, fast-forward
|
|
1848
|
+
* @details Re-verifies persisted execution-session metadata plus worktree artifacts, copies any execution-session transcript records missing from the original session file, restores the original session-backed `base-path`, executes the stash-assisted fast-forward merge sequence from `base-path`, deletes the worktree after merge success, and preserves the restored base session across closure failures. Closure intentionally treats `base-path` restoration as authoritative even when pi CLI has already started end-of-session session replacement or other housekeeping that moved the live runtime away from `worktree-path`. Runtime is dominated by session switching plus git subprocess execution. Side effects include session-file appends, active-session replacement, branch merges, stash-stack mutation, worktree deletion, and optional debug-log writes.
|
|
1695
1849
|
* @param[in] plan {PromptCommandExecutionPlan} Prompt execution plan.
|
|
1696
1850
|
* @param[in] ctx {PromptCommandSessionContext | undefined} Optional prompt-command context.
|
|
1697
1851
|
* @param[in] debugOptions {PromptCommandDebugOptions | undefined} Optional prompt debug logging context.
|
|
1698
|
-
* @return {Promise<{ mergeAttempted: boolean; mergeSucceeded: boolean; cleanupSucceeded: boolean; errorMessage?: string; activeContext?: PromptCommandSessionContext }>} Finalization facts plus the last valid active prompt-command context.
|
|
1699
|
-
* @satisfies REQ-208, REQ-209, REQ-220, REQ-245, REQ-282
|
|
1852
|
+
* @return {Promise<{ mergeAttempted: boolean; mergeSucceeded: boolean; cleanupSucceeded: boolean; errorMessage?: string; warningMessage?: string; activeContext?: PromptCommandSessionContext }>} Finalization facts plus the last valid active prompt-command context.
|
|
1853
|
+
* @satisfies REQ-208, REQ-209, REQ-220, REQ-245, REQ-282, REQ-291, REQ-292
|
|
1700
1854
|
*/
|
|
1701
1855
|
export async function finalizePromptCommandExecution(
|
|
1702
1856
|
plan: PromptCommandExecutionPlan,
|
|
@@ -1707,6 +1861,7 @@ export async function finalizePromptCommandExecution(
|
|
|
1707
1861
|
mergeSucceeded: boolean;
|
|
1708
1862
|
cleanupSucceeded: boolean;
|
|
1709
1863
|
errorMessage?: string;
|
|
1864
|
+
warningMessage?: string;
|
|
1710
1865
|
activeContext?: PromptCommandSessionContext;
|
|
1711
1866
|
}> {
|
|
1712
1867
|
let activeContext = ctx;
|
|
@@ -1749,32 +1904,14 @@ export async function finalizePromptCommandExecution(
|
|
|
1749
1904
|
activeContext,
|
|
1750
1905
|
};
|
|
1751
1906
|
}
|
|
1752
|
-
const
|
|
1753
|
-
|
|
1754
|
-
plan.basePath,
|
|
1755
|
-
);
|
|
1756
|
-
const mergeSucceeded = !mergeResult.error && mergeResult.status === 0;
|
|
1757
|
-
const errorMessage = mergeSucceeded
|
|
1758
|
-
? undefined
|
|
1759
|
-
: `ERROR: Fast-forward merge failed for worktree ${plan.worktreeDir}.`;
|
|
1760
|
-
if (debugOptions) {
|
|
1761
|
-
logDebugPromptEvent(
|
|
1762
|
-
plan.basePath,
|
|
1763
|
-
debugOptions.config,
|
|
1764
|
-
debugOptions.workflowState,
|
|
1765
|
-
plan.promptName,
|
|
1766
|
-
"merge",
|
|
1767
|
-
{ worktree_dir: plan.worktreeDir, branch_name: plan.branchName },
|
|
1768
|
-
{ success: mergeSucceeded, error: errorMessage },
|
|
1769
|
-
!mergeSucceeded,
|
|
1770
|
-
);
|
|
1771
|
-
}
|
|
1772
|
-
if (!mergeSucceeded) {
|
|
1907
|
+
const mergeFinalization = finalizePromptCommandMerge(plan, debugOptions);
|
|
1908
|
+
if (!mergeFinalization.mergeSucceeded) {
|
|
1773
1909
|
return {
|
|
1774
|
-
mergeAttempted:
|
|
1910
|
+
mergeAttempted: mergeFinalization.mergeAttempted,
|
|
1775
1911
|
mergeSucceeded: false,
|
|
1776
1912
|
cleanupSucceeded: true,
|
|
1777
|
-
errorMessage,
|
|
1913
|
+
errorMessage: mergeFinalization.errorMessage,
|
|
1914
|
+
warningMessage: mergeFinalization.warningMessage,
|
|
1778
1915
|
activeContext,
|
|
1779
1916
|
};
|
|
1780
1917
|
}
|
|
@@ -1788,17 +1925,19 @@ export async function finalizePromptCommandExecution(
|
|
|
1788
1925
|
);
|
|
1789
1926
|
} catch {
|
|
1790
1927
|
return {
|
|
1791
|
-
mergeAttempted:
|
|
1928
|
+
mergeAttempted: mergeFinalization.mergeAttempted,
|
|
1792
1929
|
mergeSucceeded: true,
|
|
1793
1930
|
cleanupSucceeded: false,
|
|
1794
1931
|
errorMessage: `ERROR: Unable to remove worktree or branch ${plan.worktreeDir}.`,
|
|
1932
|
+
warningMessage: mergeFinalization.warningMessage,
|
|
1795
1933
|
activeContext,
|
|
1796
1934
|
};
|
|
1797
1935
|
}
|
|
1798
1936
|
return {
|
|
1799
|
-
mergeAttempted:
|
|
1937
|
+
mergeAttempted: mergeFinalization.mergeAttempted,
|
|
1800
1938
|
mergeSucceeded: true,
|
|
1801
1939
|
cleanupSucceeded: true,
|
|
1940
|
+
warningMessage: mergeFinalization.warningMessage,
|
|
1802
1941
|
activeContext,
|
|
1803
1942
|
};
|
|
1804
1943
|
}
|
package/src/core/prompts.ts
CHANGED
|
@@ -22,14 +22,12 @@ import { readBundledInstruction, readBundledPrompt } from "./resources.js";
|
|
|
22
22
|
const TOOL_REFERENCE_REPLACEMENTS: Array<[RegExp, string]> = [
|
|
23
23
|
[/`req --find`/g, "`search` tool"],
|
|
24
24
|
[/`req --files-find`/g, "`files-search` tool"],
|
|
25
|
-
[/`req --references`/g, "`references` tool"],
|
|
26
25
|
[/`req --compress`/g, "`compress` tool"],
|
|
27
26
|
[/`req --tokens`/g, "`tokens` tool"],
|
|
28
27
|
[/`req --static-check`/g, "`static-check` tool"],
|
|
29
28
|
[/`req --files-static-check`/g, "`files-static-check` tool"],
|
|
30
29
|
[/\breq --find\b/g, "search tool"],
|
|
31
30
|
[/\breq --files-find\b/g, "files-search tool"],
|
|
32
|
-
[/\breq --references\b/g, "references tool"],
|
|
33
31
|
[/\breq --compress\b/g, "compress tool"],
|
|
34
32
|
[/\breq --tokens\b/g, "tokens tool"],
|
|
35
33
|
[/\breq --static-check\b/g, "static-check tool"],
|