pi-usereq 0.78.0 → 0.80.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 CHANGED
@@ -1,4 +1,4 @@
1
- # PI-useReq/pi-usereq (0.78.0)
1
+ # PI-useReq/pi-usereq (0.80.0)
2
2
 
3
3
  <p align="center">
4
4
  <img src="https://img.shields.io/badge/python-3.11%2B-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python 3.11+">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-usereq",
3
- "version": "0.78.0",
3
+ "version": "0.80.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Ogekuri/PI-useReq.git"
@@ -893,7 +893,7 @@ export function formatPromptDebugErrorFileName(
893
893
 
894
894
  /**
895
895
  * @brief Resolves the failing HTTP status carried by one finalized agent message.
896
- * @details Extracts the leading provider error status from one `message_end` assistant message whose `stopReason` equals `error`, accepting both pi `formatProviderError` display shapes (`"<status>: <body>"` and `"<prefix> (<status>): <body>"`) so provider APIs whose SDK clients throw before emitting `after_provider_response` for non-2xx statuses (the OpenAI-compatible family, including `zai`) still flush the captured provider request payload through the message lifecycle channel. Runtime is O(n) in the inspected error-message prefix length. No external state is mutated.
896
+ * @details Extracts the leading provider error status from one `message_end` assistant message whose `stopReason` equals `error`, accepting the pi `formatProviderError` display shapes (`"<status>: <body>"` and `"<prefix> (<status>): <body>"`) plus the raw SDK `error.message` shape (`"<status> <body>"`) surfaced unchanged by the agent run-failure path, so provider APIs whose SDK clients throw before emitting `after_provider_response` for non-2xx statuses (the OpenAI-compatible family, including `zai`) still flush the captured provider request payload through the message lifecycle channel. Runtime is O(n) in the inspected error-message prefix length. No external state is mutated.
897
897
  * @param[in] message {unknown} Finalized agent message forwarded by one `message_end` lifecycle event.
898
898
  * @return {number | undefined} Failing HTTP status greater than or equal to `400`, or `undefined` when the message carries no provider error status.
899
899
  * @satisfies REQ-422, REQ-423, REQ-425
@@ -911,7 +911,8 @@ export function resolveProviderErrorFlushStatusFromMessage(message: unknown): nu
911
911
  }
912
912
  const unprefixedStatus = /^(\d{3}):/.exec(candidateMessage.errorMessage)?.[1];
913
913
  const prefixedStatus = /^[^(]+\((\d{3})\): /.exec(candidateMessage.errorMessage)?.[1];
914
- const statusText = unprefixedStatus ?? prefixedStatus;
914
+ const rawSdkStatus = /^(\d{3})\s/.exec(candidateMessage.errorMessage)?.[1];
915
+ const statusText = unprefixedStatus ?? prefixedStatus ?? rawSdkStatus;
915
916
  if (statusText === undefined) {
916
917
  return undefined;
917
918
  }
@@ -824,13 +824,13 @@ export function setPiUsereqWorkflowState(
824
824
 
825
825
  /**
826
826
  * @brief Updates mutable status state for one intercepted lifecycle hook.
827
- * @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` or `agent_settled`, 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 with the runtime extension identity prefix 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.
827
+ * @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 and promotes the pending prompt-request metadata into the active run on `agent_start` while preserving an already-promoted active request across pi-host agent-run restarts such as overflow compact-and-retry recovery, captures non-aborted run duration on `agent_end` or `agent_settled`, 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 with the runtime extension identity prefix 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.
828
828
  * @param[in,out] controller {PiUsereqStatusController} Mutable status controller.
829
829
  * @param[in] hookName {PiUsereqStatusHookName} Intercepted hook name.
830
830
  * @param[in] event {unknown} Hook payload forwarded from the wrapper.
831
831
  * @param[in] ctx {ExtensionContext} Active extension context.
832
832
  * @return {void} No return value.
833
- * @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
833
+ * @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, REQ-421
834
834
  */
835
835
  export function updateExtensionStatus(
836
836
  controller: PiUsereqStatusController,
@@ -869,8 +869,18 @@ export function updateExtensionStatus(
869
869
 
870
870
  if (hookName === "agent_start") {
871
871
  controller.state.runStartTimeMs = nowMs;
872
- controller.state.activePromptRequest = controller.state.pendingPromptRequest;
873
- controller.state.pendingPromptRequest = undefined;
872
+ // Promote only when a pending request exists: the pi host restarts the agent run for
873
+ // overflow compact-and-retry recovery (agent_end -> session_before_compact ->
874
+ // session_compact -> agent_start -> retried provider request) while the originating
875
+ // prompt-command orchestration stays in flight. Overwriting the already-promoted
876
+ // active request with an undefined pending request would drop the run from controller
877
+ // state and process-scoped persistence, silencing every retried before_provider_request
878
+ // capture (REQ-421) and the later matched-success or matched-failure closure handling.
879
+ const pendingPromptRequest = controller.state.pendingPromptRequest;
880
+ if (pendingPromptRequest !== undefined) {
881
+ controller.state.activePromptRequest = pendingPromptRequest;
882
+ controller.state.pendingPromptRequest = undefined;
883
+ }
874
884
  }
875
885
 
876
886
  if (
package/src/index.ts CHANGED
@@ -294,6 +294,17 @@ function syncContextCwdMirror(ctx: { cwd?: string }, cwd: string): void {
294
294
  }
295
295
  }
296
296
 
297
+ /**
298
+ * @brief Loads the effective configuration anchored at one exact prompt-run project base.
299
+ * @details Reads the split local and global configuration scoped to the supplied absolute `projectBase` without consulting the shared runtime path state, because during worktree-backed prompt runs the runtime `base-path` resolves to the execution checkout whose untracked `.pi-usereq.json` is absent while the prompt debug gating configuration lives at the original project base that also produced the `-request` and `-prompt` debug files. Runtime is dominated by config I/O. Side effects are limited to filesystem reads.
300
+ * @param[in] projectBase {string} Absolute original project base path recorded in the prompt execution plan.
301
+ * @return {UseReqConfig} Effective configuration anchored at the exact supplied project base.
302
+ * @satisfies REQ-416, REQ-421
303
+ */
304
+ function loadPromptRunBaseConfig(projectBase: string): UseReqConfig {
305
+ return normalizeConfigPaths(projectBase, loadConfig(projectBase));
306
+ }
307
+
297
308
  /**
298
309
  * @brief Loads project configuration for the extension runtime.
299
310
  * @details Resolves the project base, loads persisted config, and normalizes configured directory paths without reading or persisting runtime-derived `base-path` or `git-path` metadata. Runtime is dominated by config I/O. Side effects are limited to filesystem reads.
@@ -1449,7 +1460,7 @@ async function finalizeMatchedPromptSuccess(
1449
1460
 
1450
1461
  /**
1451
1462
  * @brief Handles one intercepted pi lifecycle hook for pi-usereq status updates.
1452
- * @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 or whenever one finalized `message_end` assistant error message carries a leading HTTP status >= 400 (the provider-independent fallback for provider APIs whose SDK clients throw before emitting `after_provider_response` for non-2xx statuses) 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.
1463
+ * @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 by reloading the prompt debug gating configuration from the prompt run's original `base-path` (worktree-backed checkouts do not contain the untracked `.pi-usereq.json`, so the cwd-derived cached config would silently disable capture), flushes the process-scoped captured payload as one `<timestamp>-<req-command>-error-<status>` file whenever `after_provider_response` reports a status >= 400 or whenever one finalized `message_end` assistant error message carries a leading HTTP status >= 400 (the provider-independent fallback for provider APIs whose SDK clients throw before emitting `after_provider_response` for non-2xx statuses) 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.
1453
1464
  * @param[in] pi {ExtensionAPI} Active extension API instance.
1454
1465
  * @param[in,out] statusController {PiUsereqStatusController} Mutable status controller.
1455
1466
  * @param[in] hookName {PiUsereqStatusHookName} Intercepted hook name.
@@ -1524,8 +1535,13 @@ async function handleExtensionStatusEvent(
1524
1535
  ?? statusController.state.pendingPromptRequest;
1525
1536
  if (hookName === "before_provider_request" && livePromptRequest !== undefined) {
1526
1537
  const providerRequestEvent = event as { payload?: unknown };
1538
+ // The capture gate MUST resolve its gating configuration from the prompt run's ORIGINAL
1539
+ // project base: worktree-backed runs execute in a checkout whose untracked
1540
+ // `.pi-usereq.json` is absent, so the cwd-derived cached config silently reverts to
1541
+ // `DEBUG_PROMPTS_ENABLED=disable` defaults and would skip the REQ-421 capture even though
1542
+ // the base configuration already wrote the `-request` and `-prompt` debug files.
1527
1543
  capturePromptProviderRequestForDebug(
1528
- statusController.config ?? loadProjectConfig(resolveLiveBootstrapCwd(ctx.cwd)),
1544
+ loadPromptRunBaseConfig(livePromptRequest.basePath),
1529
1545
  livePromptRequest.promptName,
1530
1546
  livePromptRequest.basePath,
1531
1547
  providerRequestEvent.payload,