Skip to content

Commit 5846c08

Browse files
authored
feat!: Add worklet ecosystem, offline rendering, and processor metrics; drop legacy ScriptProcessorNode API (#65)
* feat(workspace): Add Storybook docs and interpolation strategy packages * fix(storybook): Align playground datalists with demo * chore: Commit current in-progress workspace state * chore: Remove package coverage artifacts and update Storybook links * feat: Add Hann, Blackman, and Kaiser interpolation strategy packages * refactor(core,docs): Standardize interpolation strategy IDs and params\n\n- Rename all strategy IDs (hann8, blackman8, kaiser8, lanczos8) to (hann, blackman, kaiser, lanczos)\n- Standardize on zeroCrossings for kernel width param\n- Update all code, tests, and docs for new naming and parameter conventions\n- Remove deprecated lanczos8-strategy.mdx and update navigation\n- Add and update kitchen sink playgrounds for all strategies * chore: Align interpolation strategy params, tests, and Storybook docs * chore(storybook): Reorder track and tempo controls in tempo story * feat!: Remove legacy ScriptProcessorNode API and simplify SoundTouch controls BREAKING CHANGE: PitchShifter, SimpleFilter, WebAudioBufferSource, getWebAudioNode, and FilterSupport are no longer exported from @soundtouchjs/core. SoundTouch no longer exposes rate, tempo, virtualRate, or virtualTempo. SoundTouchNode no longer exposes tempo or rate AudioParams. Remove PitchShifter, SimpleFilter, WebAudioBufferSource, getWebAudioNode, FilterSupport, minsSecs, and noop — all solely supported the deprecated ScriptProcessorNode path. AudioWorklet is supported in all targeted browsers including iOS Safari 14.5+. Simplify SoundTouch to pitch-only public control: remove rate, tempo, virtualRate, virtualTempo, rateChange, and tempoChange setters. Internal _rate and _tempo are now always derived from virtualPitch. Remove tempo and rate AudioParams from SoundTouchNode. Playback speed is controlled exclusively by mirroring playbackRate on both the source node and SoundTouchNode. Add CLAUDE.md with mandatory code change requirements: JSDoc, tests, and documentation gates, plus Conventional Commits table and project conventions. Update all READMEs, Storybook stories, and .mdx docs to reflect the current public API and remove all references to removed symbols. Consolidate three duplicate root-level .mdx files into their beginner-friendly core/ versions. * chore(docs): Enrich CLAUDE.md with commands, architecture, and project conventions Add Commands and Architecture sections documenting Nx task commands, the SoundTouch processing pipeline, AudioWorklet pattern, worklet processor bundling, interpolation strategy plugin system, test setup, and Nx auto-detection rules. Correct the test command from pnpm --filter to pnpm nx test, add feat!/BREAKING CHANGE commit row, and document required files for new worklet packages. fix(audio-worklet): Add outputChannelCount option to SoundTouchNode Add optional outputChannelCount?: 1 | 2 to SoundTouchNodeConstructorOptions so callers can connect SoundTouchNode to mono destinations without creating a separate ChannelMergerNode. Defaults to 2 (stereo). Document the existing mono input fallback in processor.ts with inline comments. Add tests for all three cases (default, 1, 2) and add an explicit mono output processor test. * feat(core,audio-worklet): Expose WSOLA timing parameters Add StretchParameters interface (sequenceMs, seekWindowMs, overlapMs, quickSeek) and setStretchParameters() method to Stretch and SoundTouch for fine-grained control of the WSOLA time-stretch algorithm at runtime. Add public overlapMs getter/setter and quickSeek getter to Stretch, making the previously-hidden timing internals accessible without replacing all parameters at once. Add SetStretchParametersMessage to the processor message union so SoundTouchNode.setStretchParameters() can queue updates to the render thread. * feat(audio-worklet): Add processOffline() for OfflineAudioContext rendering Add processOffline() helper that renders an AudioBuffer through SoundTouch in an OfflineAudioContext without requiring a live audio device. Accepts pitch, pitchSemitones, playbackRate, interpolationStrategy, stretchParameters, and sampleBufferType options. Output length is estimated as ceil(input.length / playbackRate). * feat(audio-worklet): Add processor observability metrics Processor posts framesBuffered, underrunCount, and blockCount to the main thread every 100 render blocks. SoundTouchNode stores the latest snapshot as ProcessorMetrics, exposes it via a metrics getter, and dispatches a metrics CustomEvent for event-driven monitoring. * docs(storybook): Add Getting Started guide for processorModuleUrl resolution Documents how to resolve processorModuleUrl in Vite, webpack 5, and static hosting setups, plus OfflineAudioContext usage and common first-time mistakes (registration order, CORS, relative paths, autoplay). * feat(core): Add StretchPipe interface and stretchFactory option Introduces StretchPipe as a structural interface for the time-stretch stage, implemented by the existing Stretch class. SoundTouchOptions gains a stretchFactory callback so callers can substitute a custom stage (e.g. a phase vocoder) without subclassing. Also fixes stale @cxing/ scopes and missing packages in nx.json release.projects. * feat(audio-worklet): Add phase vocoder packages Adds two new packages: - @soundtouchjs/stretch-phase-vocoder: FFT-based StretchPipe implementation using radix-2 Cooley-Tukey FFT, Hann-windowed overlap-add synthesis, and per-bin phase accumulation. Includes createPhaseVocoderFactory for drop-in use with SoundTouchOptions.stretchFactory. - @soundtouchjs/phase-vocoder-worklet: AudioWorklet integration wrapping PhaseVocoderNode (mirrors SoundTouchNode API) and PhaseVocoderProcessor (uses SoundTouch with the phase vocoder stretchFactory). Adds fftSize and overlapFactor constructor options. Full metrics observability support. * feat(audio-worklet): Add formant correction worklet Adds @soundtouchjs/formant-correction-worklet — an AudioWorkletNode that applies SoundTouch pitch-shifting with LPC-based formant preservation. Use FormantCorrectionNode instead of SoundTouchNode when pitching vocals without the chipmunk/giant timbre shift. Key additions: - lpc.ts: autocorrelate, levinsonDurbin, applyAnalysisFilter, applySynthesisFilter (LPC order 16, 512-sample Hamming window) - formant-correction-processor.ts: per-block LPC correction with formantStrength AudioParam blend (0 = raw, 1 = corrected) - FormantCorrectionNode.ts: AudioWorkletNode with pitch, pitchSemitones, playbackRate, and formantStrength AudioParams; metrics getter/event - Storybook playground with formantStrength slider and A/B toggle - Full Vitest test suite (37 tests), README, and Storybook MDX docs * feat(storybook): Add WSOLA stretch parameters and processOffline playgrounds Add StretchParametersPlayground with live sliders for sequenceMs, seekWindowMs, overlapMs, and a quickSeek toggle — all wired to SoundTouchNode.setStretchParameters() and applied immediately to the running audio graph during playback. Add ProcessOfflinePlayground that fetches a track, renders it through processOffline() in an OfflineAudioContext, then plays the resulting AudioBuffer. Shows render time, output duration, and live code sample reflecting current parameter values. Also fix a pre-existing MDX parse failure in getting-started.mdx caused by smart/curly quotes throughout the file that prevented the Storybook 9 acorn indexer from parsing the compiled MDX output. * feat: Refactor processing pipeline and update interpolation strategy integrations * chore(agents): Nx agent config * feat: Add live processor metrics to Storybook playgrounds - Wire ProcessorMetrics event listener into AudioWorkletPlayground, StretchParametersPlayground, FormantCorrectionPlayground, and PhaseVocoderPlayground; metrics panel is always visible, defaulting to 0 - Fix Storybook static build: change processor/installer imports from ?url to ?worker&url so Vite bundles each dependency inline - Add worker: { format: 'es' } and publicDir to storybook vite.config.mts - Add .github/workflows/storybook-pages.yml for GitHub Pages deployment - Restructure CI: merge test + coverage-summary into single validation job - Raise @soundtouchjs/core coverage thresholds to branches: 85, functions: 95 - Add interpolationStrategyRegistry tests to reach 85.75% branch coverage - Migrate ESLint config from .eslintrc.cjs to per-package .eslintrc.json - Add static-storybook to .gitignore * chore: Run lint in pre-commit hook * docs: Update stage and commit instructions for Husky pre-commit hook * docs: Add Husky pre-commit hook instructions to repo-management * docs(repo-management): Update stage and commit instructions for Husky pre-commit hook * docs(repo-management): Update stage and commit instructions for Husky pre-commit hook * ci: Switch Storybook Pages deploy to GitHub Actions * feat: Add processOffline and output level metrics to worklet packages - Add processOffline() to phase-vocoder-worklet and formant-correction-worklet - Add outputRms and outputPeak to ProcessorMetrics for all worklet packages - Update demo metrics panel to display outputRms and outputPeak - Update PhaseVocoderPlayground to surface expanded metrics - Update Storybook and README docs for offline rendering and observability APIs - Fix nx release changelog rules and semverBump for non-code commit types * ci: Post coverage summary as PR comment * chore(ci): Update action versions and stage-and-commit guidance
1 parent f888b71 commit 5846c08

348 files changed

Lines changed: 36918 additions & 9722 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
name: link-workspace-packages
3+
description: 'Link workspace packages in monorepos (npm, yarn, pnpm, bun). USE WHEN: (1) you just created or generated new packages and need to wire up their dependencies, (2) user imports from a sibling package and needs to add it as a dependency, (3) you get resolution errors for workspace packages (@org/*) like "cannot find module", "failed to resolve import", "TS2307", or "cannot resolve". DO NOT patch around with tsconfig paths or manual package.json edits - use the package manager''s workspace commands to fix actual linking.'
4+
---
5+
6+
# Link Workspace Packages
7+
8+
Add dependencies between packages in a monorepo. All package managers support workspaces but with different syntax.
9+
10+
## Detect Package Manager
11+
12+
Check whether there's a `packageManager` field in the root-level `package.json`.
13+
14+
Alternatively check lockfile in repo root:
15+
16+
- `pnpm-lock.yaml` → pnpm
17+
- `yarn.lock` → yarn
18+
- `bun.lock` / `bun.lockb` → bun
19+
- `package-lock.json` → npm
20+
21+
## Workflow
22+
23+
1. Identify consumer package (the one importing)
24+
2. Identify provider package(s) (being imported)
25+
3. Add dependency using package manager's workspace syntax
26+
4. Verify symlinks created in consumer's `node_modules/`
27+
28+
---
29+
30+
## pnpm
31+
32+
Uses `workspace:` protocol - symlinks only created when explicitly declared.
33+
34+
```bash
35+
# From consumer directory
36+
pnpm add @org/ui --workspace
37+
38+
# Or with --filter from anywhere
39+
pnpm add @org/ui --filter @org/app --workspace
40+
```
41+
42+
Result in `package.json`:
43+
44+
```json
45+
{ "dependencies": { "@org/ui": "workspace:*" } }
46+
```
47+
48+
---
49+
50+
## yarn (v2+/berry)
51+
52+
Also uses `workspace:` protocol.
53+
54+
```bash
55+
yarn workspace @org/app add @org/ui
56+
```
57+
58+
Result in `package.json`:
59+
60+
```json
61+
{ "dependencies": { "@org/ui": "workspace:^" } }
62+
```
63+
64+
---
65+
66+
## npm
67+
68+
No `workspace:` protocol. npm auto-symlinks workspace packages.
69+
70+
```bash
71+
npm install @org/ui --workspace @org/app
72+
```
73+
74+
Result in `package.json`:
75+
76+
```json
77+
{ "dependencies": { "@org/ui": "*" } }
78+
```
79+
80+
npm resolves to local workspace automatically during install.
81+
82+
---
83+
84+
## bun
85+
86+
Supports `workspace:` protocol (pnpm-compatible).
87+
88+
```bash
89+
cd packages/app && bun add @org/ui
90+
```
91+
92+
Result in `package.json`:
93+
94+
```json
95+
{ "dependencies": { "@org/ui": "workspace:*" } }
96+
```
97+
98+
---
99+
100+
## Examples
101+
102+
**Example 1: pnpm - link ui lib to app**
103+
104+
```bash
105+
pnpm add @org/ui --filter @org/app --workspace
106+
```
107+
108+
**Example 2: npm - link multiple packages**
109+
110+
```bash
111+
npm install @org/data-access @org/ui --workspace @org/dashboard
112+
```
113+
114+
**Example 3: Debug "Cannot find module"**
115+
116+
1. Check if dependency is declared in consumer's `package.json`
117+
2. If not, add it using appropriate command above
118+
3. Run install (`pnpm install`, `npm install`, etc.)
119+
120+
## Notes
121+
122+
- Symlinks appear in `<consumer>/node_modules/@org/<package>`
123+
- **Hoisting differs by manager:**
124+
- npm/bun: hoist shared deps to root `node_modules`
125+
- pnpm: no hoisting (strict isolation, prevents phantom deps)
126+
- yarn berry: uses Plug'n'Play by default (no `node_modules`)
127+
- Root `package.json` should have `"private": true` to prevent accidental publish

.agents/skills/monitor-ci/SKILL.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
// This file has been removed as Nx Cloud CI is not used.
2+
3+
## Status Reporting
4+
5+
The decision script handles message formatting based on verbosity. When printing messages to the user:
6+
7+
- Prepend `[monitor-ci]` to every message from the script's `message` field
8+
- For your own action messages (e.g. "Applying fix via MCP..."), also prepend `[monitor-ci]`
9+
10+
## Anti-Patterns
11+
12+
These behaviors cause real problems — racing with self-healing, losing CI progress, or wasting context:
13+
14+
| Anti-Pattern | Why It's Bad |
15+
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
16+
| Using CI provider CLIs with `--watch` flags (e.g., `gh pr checks --watch`, `glab ci status -w`) | Bypasses Nx Cloud self-healing entirely |
17+
| Writing custom CI polling scripts | Unreliable, pollutes context, no self-healing |
18+
| Cancelling CI workflows/pipelines | Destructive, loses CI progress |
19+
| Running CI checks on main agent | Wastes main agent context tokens |
20+
| Independently analyzing/fixing CI failures while polling | Races with self-healing, causes duplicate fixes and confused state |
21+
22+
**If this skill fails to activate**, the fallback is:
23+
24+
1. Use CI provider CLI for a one-time, read-only status check (single call, no watch/polling flags)
25+
2. Immediately delegate to this skill with gathered context
26+
3. Do not continue polling on main agent — it wastes context tokens and bypasses self-healing
27+
28+
## Session Context Behavior
29+
30+
If the user previously ran `/monitor-ci` in this session, you may have prior state (poll counts, last CI Attempt URL, etc.). Resume from that state unless `--fresh` is set, in which case discard it and start from Step 1.
31+
32+
## MCP Tool Reference
33+
34+
Three field sets control polling efficiency — use the lightest set that gives you what you need:
35+
36+
```yaml
37+
WAIT_FIELDS: 'cipeUrl,commitSha,cipeStatus'
38+
LIGHT_FIELDS: 'cipeStatus,cipeUrl,branch,commitSha,selfHealingStatus,verificationStatus,userAction,failedTaskIds,verifiedTaskIds,selfHealingEnabled,failureClassification,couldAutoApplyTasks,autoApplySkipped,autoApplySkipReason,shortLink,confidence,confidenceReasoning,hints,selfHealingSkippedReason,selfHealingSkipMessage'
39+
HEAVY_FIELDS: 'taskOutputSummary,suggestedFix,suggestedFixReasoning,suggestedFixDescription'
40+
```
41+
42+
The `ci_information` tool accepts `branch` (optional, defaults to current git branch), `select` (comma-separated field names), and `pageToken` (0-based pagination for long strings).
43+
44+
The `update_self_healing_fix` tool accepts a `shortLink` and an action: `APPLY`, `REJECT`, or `RERUN_ENVIRONMENT_STATE`.
45+
46+
## Default Behaviors by Status
47+
48+
The decision script returns one of the following statuses. This table defines the **default behavior** for each. User instructions can override any of these.
49+
50+
**Simple exits** — just report and exit:
51+
52+
| Status | Default Behavior |
53+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
54+
| `ci_success` | Exit with success |
55+
| `cipe_canceled` | Exit, CI was canceled |
56+
| `cipe_timed_out` | Exit, CI timed out |
57+
| `polling_timeout` | Exit, polling timeout reached |
58+
| `circuit_breaker` | Exit, no progress after 13 consecutive polls |
59+
| `environment_rerun_cap` | Exit, environment reruns exhausted |
60+
| `fix_auto_applying` | Self-healing is handling it — just record `last_cipe_url`, enter wait mode. No MCP call or local git ops needed. |
61+
| `error` | Wait 60s and loop |
62+
63+
**Statuses requiring action** — when handling these in Step 3, read `references/fix-flows.md` for the detailed flow:
64+
65+
| Status | Summary |
66+
| ------------------------ | --------------------------------------------------------------------------------------------- |
67+
| `fix_auto_apply_skipped` | Fix verified but auto-apply skipped (e.g., loop prevention). Inform user, offer manual apply. |
68+
| `fix_apply_ready` | Fix verified (all tasks or e2e-only). Apply via MCP. |
69+
| `fix_needs_local_verify` | Fix has unverified non-e2e tasks. Run locally, then apply or enhance. |
70+
| `fix_needs_review` | Fix verification failed/not attempted. Analyze and decide. |
71+
| `fix_failed` | Self-healing failed. Fetch heavy data, attempt local fix (gate check first). |
72+
| `no_fix` | No fix available. Fetch heavy data, attempt local fix (gate check first) or exit. |
73+
| `environment_issue` | Request environment rerun via MCP (gate check first). |
74+
| `self_healing_throttled` | Reject old fixes, attempt local fix. |
75+
| `no_new_cipe` | CI Attempt never spawned. Auto-fix workflow or exit with guidance. |
76+
| `cipe_no_tasks` | CI failed with no tasks. Retry once with empty commit. |
77+
78+
**Key rules (always apply):**
79+
80+
- **Git safety**: Stage specific files by name — `git add -A` or `git add .` risks committing the user's unrelated work-in-progress or secrets
81+
- **Environment failures** (OOM, command not found, permission denied): bail immediately. These aren't code bugs, so spending local-fix budget on them is wasteful
82+
- **Gate check**: Run `ci-state-update.mjs gate` before local fix attempts — if budget exhausted, print message and exit
83+
84+
## Main Loop
85+
86+
### Step 1: Initialize Tracking
87+
88+
```
89+
cycle_count = 0 # Only incremented for agent-initiated cycles (counted against --max-cycles)
90+
start_time = now()
91+
no_progress_count = 0
92+
local_verify_count = 0
93+
env_rerun_count = 0
94+
last_cipe_url = null
95+
expected_commit_sha = null
96+
agent_triggered = false # Set true after monitor takes an action that triggers new CI Attempt
97+
poll_count = 0
98+
wait_mode = false
99+
prev_status = null
100+
prev_cipe_status = null
101+
prev_sh_status = null
102+
prev_verification_status = null
103+
prev_failure_classification = null
104+
```
105+
106+
### Step 2: Polling Loop
107+
108+
Repeat until done:
109+
110+
#### 2a. Spawn subagent (FETCH_STATUS)
111+
112+
Determine select fields based on mode:
113+
114+
- **Wait mode**: use WAIT_FIELDS (`cipeUrl,commitSha,cipeStatus`)
115+
- **Normal mode (first poll or after newCipeDetected)**: use LIGHT_FIELDS
116+
117+
Call the `ci_information` tool with the determined `select` fields for the current branch. Wait for the result before proceeding.
118+
119+
#### 2b. Run decision script
120+
121+
```bash
122+
node <skill_dir>/scripts/ci-poll-decide.mjs '<subagent_result_json>' <poll_count> <verbosity> \
123+
[--wait-mode] \
124+
[--prev-cipe-url <last_cipe_url>] \
125+
[--expected-sha <expected_commit_sha>] \
126+
[--prev-status <prev_status>] \
127+
[--timeout <timeout_seconds>] \
128+
[--new-cipe-timeout <new_cipe_timeout_seconds>] \
129+
[--env-rerun-count <env_rerun_count>] \
130+
[--no-progress-count <no_progress_count>] \
131+
[--prev-cipe-status <prev_cipe_status>] \
132+
[--prev-sh-status <prev_sh_status>] \
133+
[--prev-verification-status <prev_verification_status>] \
134+
[--prev-failure-classification <prev_failure_classification>]
135+
```
136+
137+
The script outputs a single JSON line: `{ action, code, message, delay?, noProgressCount, envRerunCount, fields?, newCipeDetected?, verifiableTaskIds? }`
138+
139+
#### 2c. Process script output
140+
141+
Parse the JSON output and update tracking state:
142+
143+
- `no_progress_count = output.noProgressCount`
144+
- `env_rerun_count = output.envRerunCount`
145+
- `prev_cipe_status = subagent_result.cipeStatus`
146+
- `prev_sh_status = subagent_result.selfHealingStatus`
147+
- `prev_verification_status = subagent_result.verificationStatus`
148+
- `prev_failure_classification = subagent_result.failureClassification`
149+
- `prev_status = output.action + ":" + (output.code || subagent_result.cipeStatus)`
150+
- `poll_count++`
151+
152+
Based on `action`:
153+
154+
- **`action == "poll"`**: Print `output.message`, sleep `output.delay` seconds, go to 2a
155+
- If `output.newCipeDetected`: clear wait mode, reset `wait_mode = false`
156+
- **`action == "wait"`**: Print `output.message`, sleep `output.delay` seconds, go to 2a
157+
- **`action == "done"`**: Proceed to Step 3 with `output.code`
158+
159+
### Step 3: Handle Actionable Status
160+
161+
When decision script returns `action == "done"`:
162+
163+
1. Run cycle-check (Step 4) **before** handling the code
164+
2. Check the returned `code`
165+
3. Look up default behavior in the table above
166+
4. Check if user instructions override the default
167+
5. Execute the appropriate action
168+
6. **If action expects new CI Attempt**, update tracking (see Step 3a)
169+
7. If action results in looping, go to Step 2
170+
171+
#### Tool calls for actions
172+
173+
Several statuses require fetching additional data or calling tools:
174+
175+
- **fix_apply_ready**: Call `update_self_healing_fix` with action `APPLY`
176+
- **fix_needs_local_verify**: Call `ci_information` with HEAVY_FIELDS for fix details before local verification
177+
- **fix_needs_review**: Call `ci_information` with HEAVY_FIELDS → get `suggestedFixDescription`, `suggestedFixSummary`, `taskFailureSummaries`
178+
- **fix_failed / no_fix**: Call `ci_information` with HEAVY_FIELDS → get `taskFailureSummaries` for local fix context
179+
- **environment_issue**: Call `update_self_healing_fix` with action `RERUN_ENVIRONMENT_STATE`
180+
- **self_healing_throttled**: Call `ci_information` with HEAVY_FIELDS → get `selfHealingSkipMessage`; then call `update_self_healing_fix` for each old fix
181+
182+
### Step 3a: Track State for New-CI-Attempt Detection
183+
184+
After actions that should trigger a new CI Attempt, run:
185+
186+
```bash
187+
node <skill_dir>/scripts/ci-state-update.mjs post-action \
188+
--action <type> \
189+
--cipe-url <current_cipe_url> \
190+
--commit-sha <git_rev_parse_HEAD>
191+
```
192+
193+
Action types: `fix-auto-applying`, `apply-mcp`, `apply-local-push`, `reject-fix-push`, `local-fix-push`, `env-rerun`, `auto-fix-push`, `empty-commit-push`
194+
195+
The script returns `{ waitMode, pollCount, lastCipeUrl, expectedCommitSha, agentTriggered }`. Update all tracking state from the output, then go to Step 2.
196+
197+
### Step 4: Cycle Classification and Progress Tracking
198+
199+
When the decision script returns `action == "done"`, run cycle-check **before** handling the code:
200+
201+
```bash
202+
node <skill_dir>/scripts/ci-state-update.mjs cycle-check \
203+
--code <code> \
204+
[--agent-triggered] \
205+
--cycle-count <cycle_count> --max-cycles <max_cycles> \
206+
--env-rerun-count <env_rerun_count>
207+
```
208+
209+
The script returns `{ cycleCount, agentTriggered, envRerunCount, approachingLimit, message }`. Update tracking state from the output.
210+
211+
- If `approachingLimit` → ask user whether to continue (with 5 or 10 more cycles) or stop monitoring
212+
- If previous cycle was NOT agent-triggered (human pushed), log that human-initiated push was detected
213+
214+
#### Progress Tracking
215+
216+
- `no_progress_count`, circuit breaker (5 polls), and backoff reset are handled by ci-poll-decide.mjs (progress = any change in cipeStatus, selfHealingStatus, verificationStatus, or failureClassification)
217+
- `env_rerun_count` reset on non-environment status is handled by ci-state-update.mjs cycle-check
218+
- On new CI Attempt detected (poll script returns `newCipeDetected`) → reset `local_verify_count = 0`, `env_rerun_count = 0`
219+
220+
## Error Handling
221+
222+
| Error | Action |
223+
| ------------------------------ | ----------------------------------------------------------------------------------------------------------- |
224+
| Git rebase conflict | Report to user, exit |
225+
| `nx-cloud apply-locally` fails | Reject fix via MCP (`action: "REJECT"`), then attempt manual patch (Reject + Fix From Scratch Flow) or exit |
226+
| MCP tool error | Retry once, if fails report to user |
227+
| Subagent spawn failure | Retry once, if fails exit with error |
228+
| Decision script error | Treat as `error` status, increment `no_progress_count` |
229+
| No new CI Attempt detected | If `--auto-fix-workflow`, try lockfile update; otherwise report to user with guidance |
230+
| Lockfile auto-fix fails | Report to user, exit with guidance to check CI logs |
231+
232+
## User Instruction Examples
233+
234+
Users can override default behaviors:
235+
236+
| Instruction | Effect |
237+
| ------------------------------------------------ | --------------------------------------------------- |
238+
| "never auto-apply" | Always prompt before applying any fix |
239+
| "always ask before git push" | Prompt before each push |
240+
| "reject any fix for e2e tasks" | Auto-reject if `failedTaskIds` contains e2e |
241+
| "apply all fixes regardless of verification" | Skip verification check, apply everything |
242+
| "if confidence < 70, reject" | Check confidence field before applying |
243+
| "run 'nx affected -t typecheck' before applying" | Add local verification step |
244+
| "auto-fix workflow failures" | Attempt lockfile updates on pre-CI-Attempt failures |
245+
| "wait 45 min for new CI Attempt" | Override new-CI-Attempt timeout (default: 10 min) |

0 commit comments

Comments
 (0)