Skip to content

Fix remaining #470 console flash: hub server spawn, not just browser-open - #475

Open
richard-devbot wants to merge 8 commits into
mainfrom
fix-472-hub-server-spawn-console-flash
Open

Fix remaining #470 console flash: hub server spawn, not just browser-open#475
richard-devbot wants to merge 8 commits into
mainfrom
fix-472-hub-server-spawn-console-flash

Conversation

@richard-devbot

@richard-devbot richard-devbot commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Problem

The console-window flash from #470 is still happening — #471 fixed the wrong half of it.

Every affected file (auto-launch.js, rstack-sdlc.ts, sandbox.js, dashboard/server.js) makes two spawns:

  1. spawn(cmd, [url], { shell: true }) → opens the browser via cmd.exe /c startthis one got windowsHide in Fix Windows console-window flash on browser/runtime auto-launch #471
  2. spawn(process.execPath, [binPath, ...], { detached: true }) → launches the Business Hub server itself — this one didn't

process.execPath is node.exe, a console-subsystem executable. Spawning it detached: true without windowsHide flashes a console window on win32 regardless of shell — a separate cause from the one #471 fixed. It fires on the path users hit most: Claude Code SessionStartautoLaunchBusinessHub → this spawn, and the equivalent Pi session-start path.

Fix

Added windowsHide: true to the two missed call sites:

  • src/hooks/auto-launch.js — Claude Code hub launch
  • src/integrations/pi/rstack-sdlc.ts — Pi hub launch

autoLaunchBusinessHub now accepts an injectable spawnImpl (same convention as openBrowser/startContainerRuntime) so this is unit-testable without spawning a real process.

Verification

  • New regression test in tests/windows-console-flash-470.test.js, alongside the existing Windows: browser/runtime auto-launch briefly flashes a visible console window #470 coverage — asserts windowsHide: true on the server-launch spawn.
  • tests/windows-console-flash-470.test.js: 7/7 pass.
  • Full suite: 1559 pass / 51 fail — identical 51 failures on an unmodified tree (spawn npx ENOENT, Windows temp-dir EBUSY), the documented pre-existing sandbox limitations. None touch the changed files.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Prevented brief console windows from appearing when launching the Business Hub on Windows.
    • Improved Slack notification formatting across Discord, Microsoft Teams, and text channels.
    • Added support for Slack message fields in both standard and legacy block formats.
    • Corrected Slack message blocks to use the appropriate structure for more reliable rendering.

richardsongunde and others added 3 commits July 26, 2026 17:21
…#472)

npm audit reported 5 high-severity advisories, all tracing to one root:
a DoS/ReDoS bug in brace-expansion (GHSA-3jxr-9vmj-r5cp,
GHSA-mh99-v99m-4gvg), reachable via eslint -> minimatch@3.1.5 ->
brace-expansion@1.1.16. npm's only reported fix was eslint@10
(isSemVerMajor), which pulls in a new no-useless-assignment rule
in @eslint/js's recommended config, flagging 15 pre-existing
dead-store patterns across src/ -- too invasive for a security-only
fix.

Instead: add a root `overrides` entry (this repo already uses the
same mechanism for esbuild/protobufjs/ws) forcing brace-expansion to
the patched 5.0.8 line. Verified this reaches eslint's own tree
(minimatch@3.1.5's brace-expansion now 5.0.8) while, as documented,
leaving @earendil-works/pi-coding-agent's shrinkwrapped copy (5.0.6)
untouched -- npm honors a shrinkwrap absolutely, so overrides can't
reach it regardless.

That shrinkwrapped copy is the only remaining high-severity finding,
and it's exactly the node this gate's BUNDLED_ROOTS/
TOLERATED_BUNDLED_ADVISORIES allowlist already exists to tolerate --
added the second GHSA id to that allowlist (the gate is deliberately
strict per-advisory-id, so a newly surfaced GHSA for an
already-tolerated package still fails until consciously added).

Verified: npm run lint unchanged (0 errors, same 4 pre-existing
warnings -- confirms minimatch@3.1.5 works fine with the newer
brace-expansion at runtime), npm run typecheck clean, gate logic
simulated against real npm audit output now reports 0 blocking.
Slack notifications have never been deliverable. Both payload builders in
src/notifications/index.js emitted a block of `{ type: 'fields', fields }`,
but Block Kit has no `fields` block type — fields belong on a `section`
block. Slack rejects the entire attachment with:

    400 invalid_attachments

Verified against a live Incoming Webhook: failing before this change,
delivering successfully after it.

The bogus type had propagated to every consumer, so each one is updated to
read fields off a section block while still tolerating the old shape, which
keeps any in-flight or persisted payloads converting correctly:

  - channels/teams.js   - facts extraction
  - channels/discord.js - embed fields
  - channels/text.js    - plain-text flattening (covered by the existing
                          "slackPayloadToText renders blocks as readable
                          plain text" test, which caught this consumer)

Teams and Discord converters produce identical output to before the change.
tests/notifications-channels.test.js, harness-notifications.test.js and
notify-hook.test.js pass 21/21.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…open

#471 fixed the cmd.exe browser-open spawn (`start <url>` via shell:true) at
four call sites, but each of those files makes a SECOND spawn that #471
missed: launching the Business Hub server itself by spawning node.exe
directly with `detached: true` and no `windowsHide`.

node.exe is a console-subsystem executable. Spawning one detached without
windowsHide flashes a visible console window on win32 independent of the
shell:true/cmd.exe case #471 addressed — so the flash kept happening on
every Claude Code session start (SessionStart hook -> autoLaunchBusinessHub)
and every Pi session start, exactly where users would notice it most.

Fixed the two call sites:
  - src/hooks/auto-launch.js        (Claude Code SessionStart hook)
  - src/integrations/pi/rstack-sdlc.ts (Pi session start)

autoLaunchBusinessHub now accepts an injectable `spawnImpl` (mirroring the
existing openBrowser/startContainerRuntime convention) so the windowsHide
behavior on the server-launch spawn is unit-testable without spawning a
real background process.

Added a regression test to tests/windows-console-flash-470.test.js
alongside the existing #470 coverage. Full suite: 1559 pass / 51 fail, same
51 as an unmodified tree — all spawn ENOENT / temp-dir EBUSY, the
documented pre-existing Windows-sandbox limitations, none touching the
changed files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@strix-security

strix-security Bot commented Jul 27, 2026

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for f080458.


Reviewed by Strix
Re-run review · Configure security review settings

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@richard-devbot, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 55 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 13ad8d66-dbf6-469a-b9b4-38d3157fdde9

📥 Commits

Reviewing files that changed from the base of the PR and between f080458 and 039604e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • package.json
  • scripts/security-audit.mjs
  • src/hooks/auto-launch.js
  • tests/notifications-channels.test.js
  • tests/security-audit.test.js
  • tests/windows-console-flash-470.test.js
📝 Walkthrough

Walkthrough

Business Hub spawn paths now hide detached Windows consoles and support injected spawning for tests. Slack notification formatting now emits standard section field blocks, while converters accept both section and legacy field payloads.

Changes

Business Hub console launch

Layer / File(s) Summary
Hide detached Business Hub consoles
src/hooks/auto-launch.js, src/integrations/pi/rstack-sdlc.ts, tests/windows-console-flash-470.test.js
Business Hub launches set windowsHide: true; the auto-launch path accepts an injectable spawn implementation and has coverage for the detached Windows launch.

Slack field payload handling

Layer / File(s) Summary
Support section-based Slack fields
src/notifications/index.js, src/notifications/channels/*.js
Stage and task messages emit section blocks containing fields, and Discord, Teams, and text conversion accepts fields on section or legacy fields blocks.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: richardsongunde

Poem

A rabbit hops where consoles gleam,
Hidden windows guard the stream.
Slack fields bloom in sections bright,
Old shapes still parse just right.
“Binky!” cheers the Hub tonight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing the remaining Windows console flash in hub server spawning, not just browser-open logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-472-hub-server-spawn-console-flash

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix Win console flash on hub spawn; correct Slack Block Kit fields

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Hide Win32 console flash when launching Business Hub server via detached node.exe spawn
• Make hub auto-launch spawn injectable and add a regression test for windowsHide
• Fix Slack payload blocks (fields → section) and update Teams/Discord/Text converters
Diagram

graph TD
  H["windows-console-flash-470.test.js"] --> A["auto-launch.js"] --> B["spawn(node.exe) windowsHide"] --> C["Business Hub server"]
  H --> D["rstack-sdlc.ts"] --> B
  E["notifications/index.js"] --> F["Slack blocks: section.fields"] --> G["converters: teams/discord/text"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Centralize background process spawning
  • ➕ Prevents missing windowsHide at future detached spawn call sites
  • ➕ Allows consistent defaults (stdio/env/detached) and easier testing
  • ➖ Requires refactoring multiple files and potentially wider blast radius
  • ➖ May be hard to standardize if spawn semantics differ across features
2. Use a GUI-subsystem launcher (nodew.exe) on Windows
  • ➕ Avoids console windows even without windowsHide
  • ➕ Could simplify Windows-specific process behavior
  • ➖ Adds platform-specific branching and distribution complexity
  • ➖ May change debugging/stdio expectations
3. Validate Slack payloads against a Block Kit schema/library
  • ➕ Catches invalid block shapes (like type: 'fields') before sending
  • ➕ Improves long-term safety as payloads evolve
  • ➖ Adds dependency/runtime overhead
  • ➖ May require migration work across notification call sites

Recommendation: The PR’s approach is the right minimal, targeted fix: apply windowsHide to the missed detached node.exe spawns and add a regression test, while correcting Slack Block Kit block types and keeping converters backward-compatible. Consider a follow-up to centralize detached/background spawns to avoid repeating platform-specific flags across the codebase.

Files changed (7) +54 / -7

Bug fix (6) +25 / -6
auto-launch.jsInjectable spawn + windowsHide on hub server spawn +10/-1

Injectable spawn + windowsHide on hub server spawn

• Adds an injectable spawn implementation (spawnImpl) to make hub-launch behavior testable. Updates the detached node.exe spawn to include windowsHide: true to prevent Win32 console flashing.

src/hooks/auto-launch.js

rstack-sdlc.tsHide console flash when Pi launches hub server +5/-0

Hide console flash when Pi launches hub server

• Updates the detached node.exe spawn used to launch the Business Hub server to include windowsHide: true, preventing a console window flash on Windows.

src/integrations/pi/rstack-sdlc.ts

discord.jsRead Slack fields from section blocks (tolerate legacy type) +2/-1

Read Slack fields from section blocks (tolerate legacy type)

• Adjusts Slack-to-Discord conversion to treat fields as belonging to section blocks while still accepting legacy blocks with type: 'fields'. Prevents dropped fields after Slack payload shape correction.

src/notifications/channels/discord.js

teams.jsExtract facts from section.fields (tolerate legacy type) +2/-1

Extract facts from section.fields (tolerate legacy type)

• Updates Teams conversion to read fields from section blocks (the valid Block Kit shape) while tolerating legacy type: 'fields' payloads for backward compatibility.

src/notifications/channels/teams.js

text.jsFlatten section.fields blocks to text (tolerate legacy type) +2/-1

Flatten section.fields blocks to text (tolerate legacy type)

• Updates the plain-text converter to treat fields as part of section blocks, while still accepting legacy type: 'fields' blocks. Maintains readable text output for notifications.

src/notifications/channels/text.js

index.jsFix Slack Block Kit blocks: 'fields' → 'section' +4/-2

Fix Slack Block Kit blocks: 'fields' → 'section'

• Corrects Slack payload builders to emit fields on a section block (Block Kit-compatible) rather than an invalid 'fields' block type. This prevents Slack webhook rejections due to invalid attachments.

src/notifications/index.js

Tests (1) +29 / -1
windows-console-flash-470.test.jsRegression test for windowsHide on hub server spawns +29/-1

Regression test for windowsHide on hub server spawns

• Expands the existing #470 console-flash coverage to include the detached node.exe server-launch spawn. Uses the new spawnImpl injection to assert windowsHide: true without creating a real background process.

tests/windows-console-flash-470.test.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/windows-console-flash-470.test.js`:
- Around line 107-114: Make the autoLaunchBusinessHub spawn-branch test
deterministic by stubbing or injecting the isPortOpen check so the configured
port is guaranteed closed, and explicitly set RSTACK_NO_BUSINESS_HUB to enable
launching. Capture and restore the original RSTACK_NO_BUSINESS_HUB value
alongside the existing environment variables, preserving cleanup in all paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a68eea8f-56b8-4342-ac75-d644031ee94a

📥 Commits

Reviewing files that changed from the base of the PR and between cce8808 and f080458.

📒 Files selected for processing (7)
  • src/hooks/auto-launch.js
  • src/integrations/pi/rstack-sdlc.ts
  • src/notifications/channels/discord.js
  • src/notifications/channels/teams.js
  • src/notifications/channels/text.js
  • src/notifications/index.js
  • tests/windows-console-flash-470.test.js

Comment thread tests/windows-console-flash-470.test.js Outdated
@qodo-code-review

qodo-code-review Bot commented Jul 27, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (3)

Context used
✅ Compliance rules (platform): 300 rules
✅ Skills: 17 invoked
  code-review-pr
  claude-api
  documentation-writing
  pptx
  docx
  performance-monitoring
  security-compliance
  cso
  plan-eng-review
  design-review
  prompt-engineering
  mcp-builder
  qa-testing
  code-patterns
  xlsx
  security-owasp
  testing-qa

Grey Divider


Remediation recommended

1. Flaky port-based test ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new autoLaunchBusinessHub regression test assumes port 58471 is unused so isPortOpen()
returns false; if any process is listening on 127.0.0.1:58471, autoLaunchBusinessHub() will
early-return and never call the injected spawnImpl, causing a nondeterministic test failure.
Code

tests/windows-console-flash-470.test.js[R107-123]

+  // A high, effectively-never-bound port so isPortOpen() resolves false and
+  // the function takes the "spawn a fresh instance" branch under test.
+  const originalPort = process.env.RSTACK_BUSINESS_PORT;
+  const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
+  process.env.RSTACK_BUSINESS_PORT = '58471';
+  process.env.RSTACK_NO_BROWSER = '1';
+  try {
+    await autoLaunchBusinessHub('/tmp/project', { spawnImpl: recordingSpawn(calls) });
+  } finally {
+    if (originalPort === undefined) delete process.env.RSTACK_BUSINESS_PORT; else process.env.RSTACK_BUSINESS_PORT = originalPort;
+    if (originalNoBrowser === undefined) delete process.env.RSTACK_NO_BROWSER; else process.env.RSTACK_NO_BROWSER = originalNoBrowser;
+  }
+  assert.equal(calls.length, 1);
+  assert.equal(calls[0].cmd, process.execPath);
+  assert.equal(calls[0].options.detached, true);
+  assert.equal(calls[0].options.windowsHide, true);
+});
Relevance

●● Moderate

Flakiness-hardening sometimes rejected (e.g., tmpdir isolation rejected in PR #258); no clear
port-flake precedent.

PR-#258

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The test sets a fixed port and expects exactly one spawnImpl call, but the production
implementation checks whether the port is already accepting TCP connections and returns early if it
is, which bypasses the spawn path entirely.

tests/windows-console-flash-470.test.js[105-123]
src/hooks/auto-launch.js[10-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`tests/windows-console-flash-470.test.js` hard-codes `RSTACK_BUSINESS_PORT=58471` to force `autoLaunchBusinessHub()` down the spawn path. Because `autoLaunchBusinessHub()` performs a real TCP probe (`isPortOpen`) before spawning, a listener on that port will flip the branch and make the test fail intermittently.

### Issue Context
This test is intended to validate `windowsHide: true` on the Business Hub *server-launch* spawn. It should be deterministic and not depend on the machine’s ambient port usage.

### Fix Focus Areas
- src/hooks/auto-launch.js[10-35]
- tests/windows-console-flash-470.test.js[105-123]

### Suggested fix
Add a second injectable dependency to `autoLaunchBusinessHub`, e.g. `opts.isPortOpenImpl ?? isPortOpen`, and use that instead of calling `isPortOpen` directly. In the test, pass `isPortOpenImpl: async () => false` so the spawn path is guaranteed without relying on any specific port.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Duplicated Slack fields parsing 📜 Skill insight ⚙ Maintainability
Description
The PR repeats the same Slack Block Kit fields-handling logic (and explanatory comment) across
multiple notification channel converters, creating a DRY violation and increasing maintenance risk
if the parsing behavior changes again.
Code

src/notifications/channels/discord.js[R24-28]

+      // Fields ride on a section block; 'fields' is tolerated for older payloads.
+      if ((block.type === 'section' || block.type === 'fields') && block.fields) {
        for (const f of block.fields) {
          const raw = f.text || '';
          const parts = raw.split('\n');
Relevance

●● Moderate

No evidence team enforces DRY in converters; multi-channel code merged as-is (PR #39).

PR-#39

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1399536 requires eliminating duplicated logic. The same `block.type === 'section'
|| block.type === 'fields'` conditional and field-iteration logic was added in three separate
channel converters, indicating copy/paste duplication rather than a shared helper.

src/notifications/channels/discord.js[24-33]
src/notifications/channels/teams.js[27-40]
src/notifications/channels/text.js[26-34]
Skill: plan-eng-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Slack `fields` parsing logic is duplicated across multiple notification channel converters, violating DRY and making future schema tweaks easy to miss in one of the implementations.

## Issue Context
The same conditional logic and loop appear in `discord.js`, `teams.js`, and `text.js` to support both the correct Block Kit shape (`section` with `fields`) and a legacy tolerated shape (`type: 'fields'`).

## Fix Focus Areas
- src/notifications/channels/discord.js[24-33]
- src/notifications/channels/teams.js[27-40]
- src/notifications/channels/text.js[26-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. 58471 hardcoded test port ✓ Resolved 📜 Skill insight ⚙ Maintainability
Description
The test hardcodes the port value 58471 instead of using a named constant. This reduces
readability and makes future updates more error-prone.
Code

tests/windows-console-flash-470.test.js[R109-112]

+  const originalPort = process.env.RSTACK_BUSINESS_PORT;
+  const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
+  process.env.RSTACK_BUSINESS_PORT = '58471';
+  process.env.RSTACK_NO_BROWSER = '1';
Relevance

●● Moderate

No prior accepted/rejected reviews about replacing magic numbers with named constants in tests.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1400588 requires replacing magic numbers with named constants; the test sets
process.env.RSTACK_BUSINESS_PORT to a literal '58471' without defining a descriptive constant.

tests/windows-console-flash-470.test.js[109-112]
Skill: code-patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A literal port number is used directly in the test (`'58471'`), which violates the magic-number rule.

## Issue Context
This port is intended to be an effectively-unused port to force `isPortOpen()` to return false.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[109-112]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

4. Regression test lacks attribution metadata 📜 Skill insight ⚙ Maintainability
Description
The updated regression test comment block references #470/#471 but does not include the required
found-date and QA report path metadata. This reduces traceability for why/when the regression
coverage was added and where the original report lives.
Code

tests/windows-console-flash-470.test.js[R9-16]

+ * The original #470/#471 fix covered the browser-open spawn (cmd.exe /c
+ * start) at each call site but missed the OTHER spawn each of those files
+ * makes: launching the Business Hub SERVER itself by spawning node.exe
+ * directly with detached: true. node.exe is a console-subsystem executable,
+ * so that spawn flashes a console too, independent of the shell:true case —
+ * it kept flashing after #471 merged. Covered below for both the Claude
+ * Code hook (auto-launch.js) and the Pi integration (rstack-sdlc.ts).
+ *
Relevance

●● Moderate

No historical evidence for required regression-test attribution metadata (found-date/QA report
path).

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1400067 requires regression tests to include attribution metadata including the
issue ID, what broke, the date found, and a QA report reference. The updated header comment includes
the issue IDs and description but still lacks a found date and QA report path.

tests/windows-console-flash-470.test.js[1-18]
Skill: qa-testing

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The regression test header comment is missing required attribution metadata (date found and QA report path).

## Issue Context
Compliance requires regression tests to include: issue ID, what broke, date found, and QA report path.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[1-18]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. windows-console-flash-470.test.js regression edit 📜 Skill insight ⚙ Maintainability
Description
A new regression test was added by modifying an existing test file instead of creating a new
dedicated regression test file. This violates the requirement that regression tests be added only as
new files to avoid coupling to existing suites.
Code

tests/windows-console-flash-470.test.js[R105-123]

+test('auto-launch.js autoLaunchBusinessHub: windowsHide:true on the server-launch spawn (missed by #471)', async () => {
+  const calls = [];
+  // A high, effectively-never-bound port so isPortOpen() resolves false and
+  // the function takes the "spawn a fresh instance" branch under test.
+  const originalPort = process.env.RSTACK_BUSINESS_PORT;
+  const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
+  process.env.RSTACK_BUSINESS_PORT = '58471';
+  process.env.RSTACK_NO_BROWSER = '1';
+  try {
+    await autoLaunchBusinessHub('/tmp/project', { spawnImpl: recordingSpawn(calls) });
+  } finally {
+    if (originalPort === undefined) delete process.env.RSTACK_BUSINESS_PORT; else process.env.RSTACK_BUSINESS_PORT = originalPort;
+    if (originalNoBrowser === undefined) delete process.env.RSTACK_NO_BROWSER; else process.env.RSTACK_NO_BROWSER = originalNoBrowser;
+  }
+  assert.equal(calls.length, 1);
+  assert.equal(calls[0].cmd, process.execPath);
+  assert.equal(calls[0].options.detached, true);
+  assert.equal(calls[0].options.windowsHide, true);
+});
Relevance

● Weak

Repo commonly extends existing test files; new regression tests added in existing suite (PR #167).

PR-#167

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1400748 requires that adding regression tests be done via new test files only, but
the PR adds a new regression test block inside the existing
tests/windows-console-flash-470.test.js file.

tests/windows-console-flash-470.test.js[105-123]
Skill: qa-testing

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A regression test was added by editing an existing test file, but regression tests must be added as new test files only.

## Issue Context
The PR adds a new regression test for the hub server spawn console-flash case (missed by #471) directly into `tests/windows-console-flash-470.test.js`.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[105-123]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment on lines +24 to 28
// Fields ride on a section block; 'fields' is tolerated for older payloads.
if ((block.type === 'section' || block.type === 'fields') && block.fields) {
for (const f of block.fields) {
const raw = f.text || '';
const parts = raw.split('\n');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Duplicated slack fields parsing 📜 Skill insight ⚙ Maintainability

The PR repeats the same Slack Block Kit fields-handling logic (and explanatory comment) across
multiple notification channel converters, creating a DRY violation and increasing maintenance risk
if the parsing behavior changes again.
Agent Prompt
## Issue description
The Slack `fields` parsing logic is duplicated across multiple notification channel converters, violating DRY and making future schema tweaks easy to miss in one of the implementations.

## Issue Context
The same conditional logic and loop appear in `discord.js`, `teams.js`, and `text.js` to support both the correct Block Kit shape (`section` with `fields`) and a legacy tolerated shape (`type: 'fields'`).

## Fix Focus Areas
- src/notifications/channels/discord.js[24-33]
- src/notifications/channels/teams.js[27-40]
- src/notifications/channels/text.js[26-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +9 to +16
* The original #470/#471 fix covered the browser-open spawn (cmd.exe /c
* start) at each call site but missed the OTHER spawn each of those files
* makes: launching the Business Hub SERVER itself by spawning node.exe
* directly with detached: true. node.exe is a console-subsystem executable,
* so that spawn flashes a console too, independent of the shell:true case —
* it kept flashing after #471 merged. Covered below for both the Claude
* Code hook (auto-launch.js) and the Pi integration (rstack-sdlc.ts).
*

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

2. Regression test lacks attribution metadata 📜 Skill insight ⚙ Maintainability

The updated regression test comment block references #470/#471 but does not include the required
found-date and QA report path metadata. This reduces traceability for why/when the regression
coverage was added and where the original report lives.
Agent Prompt
## Issue description
The regression test header comment is missing required attribution metadata (date found and QA report path).

## Issue Context
Compliance requires regression tests to include: issue ID, what broke, date found, and QA report path.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[1-18]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread tests/windows-console-flash-470.test.js
Comment thread tests/windows-console-flash-470.test.js Outdated
richard-devbot and others added 5 commits July 29, 2026 20:06
Qodo flagged four issues on the eslint/brace-expansion security fix:
- no test coverage for the TOLERATED_BUNDLED_ADVISORIES allowlist change
- brace-expansion@5.0.8 declares engines.node "20 || >=22", excluding the
  Node 18 CI lane
- the ">=5.0.8" override is unbounded and can float to a future major
- the script comment mis-attributed the version bump to an eslint 9->10
  bump that never happened (the real mechanism is the root override)

Fix: bound the override to an exact "5.0.8" pin; export the pure
tolerate/block decision logic from security-audit.mjs (evaluateAdvisories,
isFullyBundled, advisoryIds) behind a main-guard so it's unit-testable
without shelling out to npm audit, and add tests/security-audit.test.js
covering the tolerate/block/allowlist-miss/severity-threshold paths, plus
a pinned-allowlist regression test; correct the stale comment to document
the real mechanism and the accepted Node 18 engines trade-off (no
brace-expansion release fixes both GHSAs while keeping Node 18 support;
it's a devDependency-only path and no engine-strict is set, so this
doesn't fail CI in practice).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… path

CodeRabbit flagged that discord.js/teams.js/text.js all gained a branch
tolerating legacy block.type === 'fields' payloads (alongside the correct
section+fields shape), but only the section path was exercised in tests
— the compatibility guarantee could regress silently. Add a test that
feeds a legacy { type: 'fields', fields: [...] } block through all three
converters.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…abbit)

The regression test hardcoded RSTACK_BUSINESS_PORT=58471 assuming the port
would be closed, but autoLaunchBusinessHub's real isPortOpen() does a live
TCP probe — a listener on that port (however unlikely) would flip the
branch and fail the test nondeterministically. It also didn't guard against
an inherited RSTACK_NO_BUSINESS_HUB=1 short-circuiting the function before
the spawn.

Fix: add an injectable isPortOpenImpl (mirrors the existing spawnImpl
convention) to autoLaunchBusinessHub, stub it in the test to guarantee the
spawn branch, name the placeholder port as a constant, and explicitly
clear/restore RSTACK_NO_BUSINESS_HUB alongside the other env vars.

Skipped (not applicable): qodo's "regression test lacks attribution
metadata" (date-found/QA-report-path) — no other test in this repo follows
that format, so adding it here would be a one-off convention, not a fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-type' into fix-472-hub-server-spawn-console-flash
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants