Skip to content

Automatic Sync: Merge changes from stable/ballerina to main - #2454

Open
choreo-cicd wants to merge 41 commits into
mainfrom
sync/main-stable/ballerina-1785772807
Open

Automatic Sync: Merge changes from stable/ballerina to main#2454
choreo-cicd wants to merge 41 commits into
mainfrom
sync/main-stable/ballerina-1785772807

Conversation

@choreo-cicd

@choreo-cicd choreo-cicd commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

This PR syncs changes from stable/ballerina to the main branch.

Automated PR created by GitHub Actions.

Summary by CodeRabbit

  • New Features

    • ICP features now appear only when supported, providing a clearer experience across environments.
    • Improved recovery automatically refreshes project structure after artifact retrieval failures.
    • Array editors now preserve commas within quoted values, templates, and nested expressions.
  • Bug Fixes

    • Fixed expression parsing for non-interpolation editors.
    • Added clearer validation for malformed TOML escape sequences.
    • Improved project navigation and sidebar reliability.
  • Updates

    • Updated support contact information for usage-limit assistance.
    • Improved security safeguards across the application.

samithkavishke and others added 30 commits June 18, 2026 15:31
Fix the blueChip rendering issue for the rc1
Fix e2e tests with the vscode update
Change Copilot quota contact email to support@wso2.com
Merge "ballerina-5.12.2" into "stable/ballerina"
Improve error on invalid escape sequence
…loading

Recover project structure with a full rebuild when the initial artifacts fetch fails
Merge "ballerina-5.12.3" into "stable/ballerina"
pasindufernando1 and others added 11 commits July 30, 2026 16:37
Address review feedback on the trivy fixes:

- The immutable pin in .pnpmfile.cjs was unconditional, so it rewrote every
  request to 3.8.3 - including sass@1.89.0, which declares `immutable: ^5.0.2`.
  Scope the pin to the 3.x line and hold 5.x at 5.1.8 via globalOverrides
  (5.0.0-5.1.7 are affected by CVE-2026-59879/59880). swagger-ui-react keeps
  3.8.3, so the .trivyignore entries still apply.

- Remove the tmp@0.2.6 and undici@7.24.0 pins. globalOverrides wins over the
  readPackage hook under pnpm 10, so both were dead code: the lockfile resolves
  tmp to 0.2.7 and undici to 8.5.0 either way. Document that ordering inline so
  the precedence note is not reverted.

Trivy: both rush lockfiles report 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Remove ICP for ballerina-ext users
Fix side panel crash for a list element with a comma
Merge "ballerina-5.12.4" into "stable/ballerina"
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request updates dependency security controls, adds ICP support gating across the Ballerina extension and visualizer, recovers failed project artifacts, improves raw-array editing, stabilizes Playwright tests, and updates validation and support messaging.

Changes

Dependency security updates

Layer / File(s) Summary
Security policy and override configuration
.trivyignore, common/config/rush/*
Trivy guidance and Rush overrides now document and apply updated security dependency pins.
Dependency package pins
common/autoinstallers/rush-plugins/package.json, workspaces/*/package.json
brace-expansion, undici, and adm-zip versions were updated.

Build token wiring

Layer / File(s) Summary
Build environment
.github/actions/build/action.yml
The build action passes its configured token as GITHUB_TOKEN.

ICP support gating

Layer / File(s) Summary
Extension support detection and service gating
workspaces/ballerina/ballerina-extension/..., workspaces/ballerina/ballerina-core/...
ICP support is detected from the WSO2 Integrator extension and applied to activation, commands, execution checks, metadata, and RPC operations.
Visualizer ICP rendering
workspaces/ballerina/ballerina-visualizer/...
Visualizer components receive isICPSupported and conditionally fetch or render ICP state and controls.

Artifact recovery

Layer / File(s) Summary
Artifact retrieval recovery
workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts
Failed artifact retrievals trigger a guarded full refresh, with snapshot restoration when recovery fails.

Raw array editing

Layer / File(s) Summary
Raw array parsing and serialization
workspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.ts, utils.ts, test/*
Raw array parsing and serialization now handle nested expressions, quoted separators, templates, interpolations, and trailing elements.
Array editor and expression handling
FormArrayEditor.tsx, MultiModeExpressionEditor/.../CodeUtils.ts
Array values are preserved directly, key mismatches are repaired, and orphan-token filtering is limited to interpolation streams.

End-to-end test stability

Layer / File(s) Summary
Shared Playwright navigation helpers
workspaces/ballerina/ballerina-extension/e2e-test/...
Tree selectors tolerate VS Code descriptions and escaped labels, and sidebar setup activates the WSO2 Integrator tab.
Playwright test consumers
run-concurrent/*, run-conflict/*, utils/helpers/setup.ts
Existing tests use the shared selector, and the VS Code version is pinned.

Validation and support messaging

Layer / File(s) Summary
Validation and support text
workspaces/ballerina/ballerina-extension/src/features/ai/..., workspaces/ballerina/ballerina-visualizer/...
Quota messages use support@wso2.com, and invalid TOML escape sequences receive specific errors.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Extension
  participant Config
  participant RPCLayer
  participant Visualizer
  Extension->>Config: Check isICPSupported()
  Config-->>Extension: Return support status
  Extension->>RPCLayer: Build visualizer context
  RPCLayer->>Visualizer: Provide isICPSupported metadata
  Visualizer->>Visualizer: Gate ICP calls and controls
Loading

Possibly related PRs

Suggested reviewers: gigara, hevayo

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description states the sync purpose but omits most required template sections, including goals, testing, security checks, release notes, and documentation. Complete the required sections and document the sync scope, included changes, testing, security checks, documentation impact, and release information.
Docstring Coverage ⚠️ Warning Docstring coverage is 22.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: an automated merge from stable/ballerina into main.
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 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch sync/main-stable/ballerina-1785772807
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/main-stable/ballerina-1785772807

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.5)
common/config/rush/pnpm-config.json

File contains syntax errors that prevent linting: Line 1: JSON standard does not allow comments.; Line 5: End of file expected; Line 8: JSON standard does not allow comments.; Line 20: End of file expected; Line 20: End of file expected; Line 20: End of file expected; Line 20: End of file expected; Line 22: JSON standard does not allow comments.; Line 36: JSON standard does not allow comments.; Line 46: JSON standard does not allow comments.; Line 61: JSON standard does not allow comments.; Line 79: JSON standard does not allow comments.; Line 91: End of file expected; Line 91: End of file expected; Line 92: Expected a property but instead found '// Security overrides — keep in sync with trivy findings and with the'.; Line 91: End of file expected; Line 92: End of file expected; Line 102: End of file expected; Line 102: End of file expected; Line 102: End of file expected; Line 102: End of file expected; Line 109: End of file expected; Line 109: End of file expected; Line 109: End of f

... [truncated 3538 characters] ...

an object, or a literal but instead found '// "fsevents"'.; Line 212: End of file expected; Line 213: End of file expected; Line 216: JSON standard does not allow comments.; Line 228: End of file expected; Line 228: End of file expected; Line 229: Expected a property but instead found '// "request": "*"'.; Line 228: End of file expected; Line 229: End of file expected; Line 233: JSON standard does not allow comments.; Line 240: End of file expected; Line 240: End of file expected; Line 240: End of file expected; Line 240: End of file expected; Line 242: JSON standard does not allow comments.; Line 254: End of file expected; Line 254: End of file expected; Line 255: Expected a property but instead found '// "dependencies": {'.; Line 254: End of file expected; Line 255: End of file expected


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.

@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: 8

🤖 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 `@common/config/rush/pnpm-config.json`:
- Around line 102-151: Replace the remaining open-ended security override ranges
in the pnpm configuration with exact reviewed remediation versions, including
lodash, `@babel/core`, form-data, tmp, undici, and the other cited entries at
lines 102, 112, 126, 128, 141, 147, and 148. Use lodash 4.18.0 and tmp 0.2.7,
and reuse the reviewed undici version documented in .pnpmfile.cjs; preserve
scoped selectors where needed while pinning each value exactly.

In
`@workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/helpers/sidebar.ts`:
- Around line 31-42: Update waitForBISidebarTreeView to use a single deadline
for activity-tab activation and BI view selector polling, rather than allowing
the initial wait and polling to each consume the full timeout. While time
remains, retry locating and activating the activity tab, including clicking it
when it becomes visible but is not checked, then pass only the remaining time to
the selector polling so the overall function stays within the requested timeout.

In `@workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts`:
- Around line 114-119: Update updateProjectArtifacts and the
artifactRecoveryInProgress flow so notifications received during recovery are
recorded instead of returned and discarded. After the current rebuild completes,
detect the pending notification and coalesce it into one additional forced
refresh, then resume accepting incremental updates only after that refresh
finishes.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts`:
- Around line 303-304: Update the orphan-filter setup in the interpolation path
around hasInterpolation and getTokenIndicesInClosedExpressionRanges so the
safe-token index Set includes both tokens inside closed interpolation ranges and
tokens in non-interpolation sections. Preserve filtering of genuine orphan
tokens while retaining literal template text outside START_EVENT/END_EVENT
ranges.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.ts`:
- Around line 118-124: Update buildStringArray to coerce each el.value to a
string before trimming, rather than relying on the compile-time cast. Preserve
the existing empty-value fallback and array formatting while ensuring numeric,
boolean, and other primitive values cannot cause .trim() to throw.
- Around line 46-107: Update stringToRawArrayElements to track an explicit
escape state while scanning quoted strings, rather than determining quote
closure solely from the previous character. Ensure escaped backslashes do not
escape the following quote, so valid separators after strings such as "a\\", b
are recognized correctly; preserve existing template and nesting behavior.

In
`@workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/utils.ts`:
- Around line 157-166: Update the union-type validation flow around the string
alternative so an `Invalid escape sequence ...` result from the string case is
propagated before returning the generic `Enter a valid value for ${type}.`
message. Preserve the existing generic fallback for union values without a
detailed string-validation error, using the detailed result produced by the
string branch.
- Line 20: The TOML_INVALID_ESCAPE_PATTERN currently captures only the first
character of malformed Unicode escapes; update it to capture the complete
malformed \u or \U payload, including invalid or missing digits, so diagnostics
report the full sequence. Add regression tests covering inputs such as "\u12G4"
and "\u123" and assert that the reported invalid escape includes the complete
malformed payload.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 95468271-1db1-4b33-a63d-a3acc9de9095

📥 Commits

Reviewing files that changed from the base of the PR and between 1857c36 and cc8c51e.

⛔ Files ignored due to path filters (2)
  • common/autoinstallers/rush-plugins/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • common/config/rush/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (33)
  • .github/actions/build/action.yml
  • .trivyignore
  • common/autoinstallers/rush-plugins/package.json
  • common/config/rush/.pnpmfile.cjs
  • common/config/rush/pnpm-config.json
  • workspaces/api-designer/api-designer-extension/package.json
  • workspaces/ballerina/ballerina-core/src/state-machine-types.ts
  • workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/run-concurrent/run-concurrent.spec.ts
  • workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/run-conflict/run-conflict.spec.ts
  • workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/helpers/setup.ts
  • workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/helpers/sidebar.ts
  • workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/pages/ProjectExplorer.ts
  • workspaces/ballerina/ballerina-extension/package.json
  • workspaces/ballerina/ballerina-extension/src/RPCLayer.ts
  • workspaces/ballerina/ballerina-extension/src/extension.ts
  • workspaces/ballerina/ballerina-extension/src/features/ai/utils/ai-client.ts
  • workspaces/ballerina/ballerina-extension/src/features/bi/activator.ts
  • workspaces/ballerina/ballerina-extension/src/features/icp/activator.ts
  • workspaces/ballerina/ballerina-extension/src/rpc-managers/icp-service/rpc-manager.ts
  • workspaces/ballerina/ballerina-extension/src/utils/config.ts
  • workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts
  • workspaces/ballerina/ballerina-side-panel/package.json
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/FormArrayEditor.tsx
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.ts
  • workspaces/ballerina/ballerina-side-panel/src/components/editors/utils.ts
  • workspaces/ballerina/ballerina-side-panel/test/rawValueUtils.test.mjs
  • workspaces/ballerina/ballerina-visualizer/src/MainPanel.tsx
  • workspaces/ballerina/ballerina-visualizer/src/views/AIPanel/components/AIChat/index.tsx
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/utils.ts
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/PackageOverview/index.tsx
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/WorkspaceOverview/index.tsx
  • workspaces/mi/mi-extension/package.json

Comment on lines 102 to +151
"lodash": ">=4.18.0",
"brace-expansion@>=5.0.0 <6": "5.0.6",
"axios": ">=1.16.0",
"hono": ">=4.12.21",
"shell-quote": ">=1.8.4"
// brace-expansion CVE-2026-13149 is fixed per line (1.1.16 / 2.1.2 /
// 5.0.7); CVE-2026-14257 covers everything <= 5.0.7 and is only fixed in
// 5.0.8, which upstream has not backported to 1.x/2.x. 5.0.8 is not a
// drop-in replacement for those lines (it dropped the CommonJS default
// export that minimatch 3.x/5.x call), so they stay on the 13149 fix
// version and the residual 14257 finding is scoped out in .trivyignore.
"brace-expansion@>=1 <2": "1.1.16",
"brace-expansion@>=2 <3": "2.1.2",
"brace-expansion@>=5.0.0 <6": "5.0.8",
"@babel/core": ">=7.29.6",
// Security fix: no 1.x fix; force the 2.x line, at the version fixing a
// follow-up advisory on the earlier 2.x releases. Transitive-only, pulled
// in by @modelcontextprotocol/sdk's optional Hono server transport,
// which the extensions do not use.
"@hono/node-server": "2.0.10",
"axios@<1.18.0": "1.18.0",
// Both lines are affected by CVE-2026-12590 and each has its own fix.
"body-parser@>=1 <2": "1.20.6",
"body-parser@>=2 <3": "2.3.0",
"dompurify": "3.4.12",
// Security fix: 3.1.4 is the first 3.x release fixing both reported
// findings.
"fast-uri": "3.1.4",
"form-data": ">=4.0.6",
"hono": "4.12.27",
"http-proxy-middleware": ">=3.0.6",
// The 3.x line has no fix for CVE-2026-59879/59880 and stays pinned in
// .pnpmfile.cjs for swagger-ui-react (see .trivyignore). sass declares
// `immutable: ^5.0.2`, so hold the 5.x line at the first patched release
// — 5.0.0 through 5.1.7 are affected by the same two advisories.
"immutable@>=5 <6": "5.1.8",
// js-yaml v3 has no in-line fix; the fix only lands in v4.3.0+. Force
// all consumers to v4 — revert with a narrower selector if a workspace
// package needs the v3 sync API.
"js-yaml": "4.3.0",
// Security fix: scoped to the 5.x line (the only one in the tree, via
// markdown-it 14) so a v6 consumer is not forced backwards.
"linkify-it@5": "5.0.2",
"markdown-it": ">=14.2.0",
// Security fix: path traversal via source map auto-loading (8.5.18) on
// top of the earlier information-disclosure fix (8.5.12).
"postcss@8": "8.5.18",
"protobufjs@>=7 <8": "7.6.5",
"shell-quote": "1.9.0",
"tmp": ">=0.2.7",
"undici": ">=7.28.0",
// Security fix: scoped to the 5.x line so a future 6.x consumer is not
// forced backwards.
"webpack-dev-server@>=5 <6": "5.2.6"

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.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Replace the remaining open security overrides with exact versions.

Lines 102, 112, 126, 128, 141, 147, and 148 use >= despite lines 97-101 requiring exact pins. These ranges can resolve an unreviewed newer major version during lockfile regeneration. They also leave the lockfile on an older safe floor when a later remediation must be selected.

Set each override to the reviewed remediation version. For example, use lodash: "4.18.0", tmp: "0.2.7", and the reviewed undici version documented in .pnpmfile.cjs.

🧰 Tools
🪛 Biome (2.5.5)

[error] 102-102: End of file expected

(parse)


[error] 102-102: End of file expected

(parse)


[error] 102-102: End of file expected

(parse)


[error] 102-108: End of file expected

(parse)


[error] 109-109: End of file expected

(parse)


[error] 109-109: End of file expected

(parse)


[error] 109-109: End of file expected

(parse)


[error] 109-109: End of file expected

(parse)


[error] 110-110: End of file expected

(parse)


[error] 110-110: End of file expected

(parse)


[error] 110-110: End of file expected

(parse)


[error] 110-110: End of file expected

(parse)


[error] 111-111: End of file expected

(parse)


[error] 111-111: End of file expected

(parse)


[error] 111-111: End of file expected

(parse)


[error] 111-111: End of file expected

(parse)


[error] 112-112: End of file expected

(parse)


[error] 112-112: End of file expected

(parse)


[error] 112-112: End of file expected

(parse)


[error] 112-116: End of file expected

(parse)


[error] 117-117: End of file expected

(parse)


[error] 117-117: End of file expected

(parse)


[error] 117-117: End of file expected

(parse)


[error] 117-117: End of file expected

(parse)


[error] 118-118: End of file expected

(parse)


[error] 118-118: End of file expected

(parse)


[error] 118-118: End of file expected

(parse)


[error] 118-119: End of file expected

(parse)


[error] 120-120: End of file expected

(parse)


[error] 120-120: End of file expected

(parse)


[error] 120-120: End of file expected

(parse)


[error] 120-120: End of file expected

(parse)


[error] 121-121: End of file expected

(parse)


[error] 121-121: End of file expected

(parse)


[error] 121-121: End of file expected

(parse)


[error] 121-121: End of file expected

(parse)


[error] 122-122: End of file expected

(parse)


[error] 122-122: End of file expected

(parse)


[error] 122-122: End of file expected

(parse)


[error] 122-124: End of file expected

(parse)


[error] 125-125: End of file expected

(parse)


[error] 125-125: End of file expected

(parse)


[error] 125-125: End of file expected

(parse)


[error] 125-125: End of file expected

(parse)


[error] 126-126: End of file expected

(parse)


[error] 126-126: End of file expected

(parse)


[error] 126-126: End of file expected

(parse)


[error] 126-126: End of file expected

(parse)


[error] 127-127: End of file expected

(parse)


[error] 127-127: End of file expected

(parse)


[error] 127-127: End of file expected

(parse)


[error] 127-127: End of file expected

(parse)


[error] 128-128: End of file expected

(parse)


[error] 128-128: End of file expected

(parse)


[error] 128-128: End of file expected

(parse)


[error] 128-132: End of file expected

(parse)


[error] 133-133: End of file expected

(parse)


[error] 133-133: End of file expected

(parse)


[error] 133-133: End of file expected

(parse)


[error] 133-136: End of file expected

(parse)


[error] 137-137: End of file expected

(parse)


[error] 137-137: End of file expected

(parse)


[error] 137-137: End of file expected

(parse)


[error] 137-139: End of file expected

(parse)


[error] 140-140: End of file expected

(parse)


[error] 140-140: End of file expected

(parse)


[error] 140-140: End of file expected

(parse)


[error] 140-140: End of file expected

(parse)


[error] 141-141: End of file expected

(parse)


[error] 141-141: End of file expected

(parse)


[error] 141-141: End of file expected

(parse)


[error] 141-143: End of file expected

(parse)


[error] 144-144: End of file expected

(parse)


[error] 144-144: End of file expected

(parse)


[error] 144-144: End of file expected

(parse)


[error] 144-144: End of file expected

(parse)


[error] 145-145: End of file expected

(parse)


[error] 145-145: End of file expected

(parse)


[error] 145-145: End of file expected

(parse)


[error] 145-145: End of file expected

(parse)


[error] 146-146: End of file expected

(parse)


[error] 146-146: End of file expected

(parse)


[error] 146-146: End of file expected

(parse)


[error] 146-146: End of file expected

(parse)


[error] 147-147: End of file expected

(parse)


[error] 147-147: End of file expected

(parse)


[error] 147-147: End of file expected

(parse)


[error] 147-147: End of file expected

(parse)


[error] 148-148: End of file expected

(parse)


[error] 148-148: End of file expected

(parse)


[error] 148-148: End of file expected

(parse)


[error] 148-150: End of file expected

(parse)


[error] 151-151: End of file expected

(parse)


[error] 151-151: End of file expected

(parse)


[error] 151-151: End of file expected

(parse)

🤖 Prompt for 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.

In `@common/config/rush/pnpm-config.json` around lines 102 - 151, Replace the
remaining open-ended security override ranges in the pnpm configuration with
exact reviewed remediation versions, including lodash, `@babel/core`, form-data,
tmp, undici, and the other cited entries at lines 102, 112, 126, 128, 141, 147,
and 148. Use lodash 4.18.0 and tmp 0.2.7, and reuse the reviewed undici version
documented in .pnpmfile.cjs; preserve scoped selectors where needed while
pinning each value exactly.

Comment on lines 31 to +42
export async function waitForBISidebarTreeView(page: ExtendedPage, timeout: number = 30000): Promise<void> {
try {
const activityTab = page.page.locator(`[role="tab"][aria-label="${BI_INTEGRATOR_LABEL}"]`).first();
await activityTab.waitFor({ state: 'visible', timeout: Math.min(timeout, 15000) });
const isActive = await activityTab.evaluate((el) => el.classList.contains('checked')).catch(() => false);
if (!isActive) {
await activityTab.click();
}
} catch {
// Activity tab not ready yet; fall through to selector polling below,
// which throws with a detailed error if the view never appears.
}

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep activity-tab activation inside the timeout budget.

waitForBISidebarTreeView(page, 60000) can wait 15 seconds for the activity tab and then spend another 60 seconds in selector polling. If the tab becomes visible after the first wait, this code never clicks it, so the BI view can remain detached during a slow cold start. Use one deadline for activation and selector polling, and retry activation while time remains.

🤖 Prompt for 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.

In
`@workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/helpers/sidebar.ts`
around lines 31 - 42, Update waitForBISidebarTreeView to use a single deadline
for activity-tab activation and BI view selector polling, rather than allowing
the initial wait and polling to each consume the full timeout. While time
remains, retry locating and activating the activity tab, including clicking it
when it becomes visible but is not checked, then pass only the remaining time to
the selector polling so the overall function stays within the requested timeout.

Comment on lines 114 to +119
export async function updateProjectArtifacts(publishedArtifacts: ArtifactsNotification): Promise<void> {
// A recovery rebuild is already running; it fetches the post-edit state, so this
// notification's changes are covered by the rebuild.
if (artifactRecoveryInProgress) {
return;
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not discard notifications during recovery.

A notification can arrive after the forced rebuild reads artifact state but before Line 117 clears the guard. This return drops that update, and the rebuild can commit an older project structure with no later notification to correct it.

Record that a notification arrived during recovery. After the current rebuild completes, coalesce and run one further forced refresh before accepting incremental updates.

🤖 Prompt for 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.

In `@workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts`
around lines 114 - 119, Update updateProjectArtifacts and the
artifactRecoveryInProgress flow so notifications received during recovery are
recorded instead of returned and discarded. After the current rebuild completes,
detect the pending notification and coalesce it into one additional forced
refresh, then resume accepting incremental updates only after that refresh
finishes.

Comment on lines +303 to +304
// The orphan filter only applies to interpolation-based editors (e.g. prompt/template)
const hasInterpolation = tokens.some(token => token.type === TokenType.START_EVENT);

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Locate getTokenIndicesInClosedExpressionRanges to confirm its semantics.
fd -t f 'CodeUtils.ts' workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor \
  --exec rg -n -B2 -A25 'function getTokenIndicesInClosedExpressionRanges' {}

Repository: wso2/vscode-extensions

Length of output: 160


🏁 Script executed:

#!/bin/bash
set -e

echo "== locate CodeUtils.ts =="
fd -t f 'CodeUtils\.ts$' . | sed -n '1,40p'

echo "== search symbol =="
rg -n "getTokenIndicesInClosedExpressionRanges|TokenType\.START_EVENT|insideClosedRange|orphan" . -S | sed -n '1,200p'

echo "== repo files around target =="
git ls-files | grep -F 'workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts' || true

Repository: wso2/vscode-extensions

Length of output: 50379


🏁 Script executed:

#!/bin/bash
set -e

echo "== exact target file =="
ls -la "workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts" 2>/dev/null || true
wc -l "workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts" 2>/dev/null || true

echo "== relevant file contents 260-345 =="
sed -n '260,345p' "workspaces/ballerina/ballerina-side-panel/src/components/readers/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts" 2>/dev/null || true

echo "== bounded symbol search =="
rg -n --glob '!**/dist/**' --glob '!**/build/**' --glob '!**/node_modules/**' --glob '!**/*.min.js' --glob '!**/*.map' \
  'getTokenIndicesInClosedExpressionRanges|function getTokenIndicesInClosedExpressionRanges|const getTokenIndicesInClosedExpressionRanges|export .*getTokenIndicesInClosedExpressionRanges' \
  .

Repository: wso2/vscode-extensions

Length of output: 1569


🏁 Script executed:

#!/bin/bash
set -e

echo "== utils implementation =="
sed -n '150,220p' "workspaces/ballerina/ballerina-side-panelsrc/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts" 2>/dev/null || true

echo "== utils implementation exact =="
sed -n '150,220p' "workspaces/ballerina/ballerina-side-panel/src/components/e0139/ditors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts" 2>/dev/null || true

echo "== try case-insensitive exact token search =="
rg -n --glob '!**/dist/**' --glob '!**/build/**' --glob '!**/node_modules/**' --glob '!**/*.min.js' --glob '!**/*.map' "getTokenIndicesInClosedExpressionRanges" workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor

Repository: wso2/vscode-extensions

Length of output: 869


🏁 Script executed:

#!/bin/bash
set -e

file="workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts"

echo "== utils implementation =="
sed -n '170,235p' "$file"

echo "== imports and token types in CodeUtils =="
sed -n '1,80p' "workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts"

echo "== deterministic simulation of helper semantics from source text =="
python3 - <<'PY'
from pathlib import Path
import re
file = Path("workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts")
src = file.read_text()
m = re.search(r'export const getTokenIndicesInClosedExpressionRanges = .*?\n}', src, re.S)
print(m.group(0))
PY

Repository: wso2/vscode-extensions

Length of output: 6359


Also keep tokens outside interpolation ranges in the orphan filter.

getTokenIndicesInClosedExpressionRanges builds a Set only for tokens between a START_EVENT and the next END_EVENT. For mixed template text, literal tokens outside ${...} indices are not present in insideClosedRange, so the filter removes non-orphan plain text. Add both closed interpolation ranges and non-interpolation sections to the safe index Set before dropping orphans.

🤖 Prompt for 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.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts`
around lines 303 - 304, Update the orphan-filter setup in the interpolation path
around hasInterpolation and getTokenIndicesInClosedExpressionRanges so the
safe-token index Set includes both tokens inside closed interpolation ranges and
tokens in non-interpolation sections. Preserve filtering of genuine orphan
tokens while retaining literal template text outside START_EVENT/END_EVENT
ranges.

Comment on lines +46 to +107
for (let i = 0; i < s.length; i++) {
const char = s[i];
const prev = s[i - 1];

// within a quoted string, only its closing quote is significant
if (inString) {
if (char === '"' && prev !== "\\") {
inString = false;
}
current += char;
continue;
}

// within the interpolation of a template, the expression ends the interpolation alone
if (interpolationDepth > 0) {
if (char === '"') {
inString = true;
} else if (char === "{") {
interpolationDepth++;
} else if (char === "}") {
interpolationDepth--;
}
current += char;
continue;
}

// within the text of a template, only an interpolation and the closing backtick are significant
if (inTemplate) {
if (char === "{" && prev === "$") {
interpolationDepth++;
} else if (char === "`") {
inTemplate = false;
}
current += char;
continue;
}

// handle template boundaries
if (char === "`") {
inTemplate = true;
current += char;
continue;
}

// handle string boundaries
if (char === '"' && prev !== "\\") {
inString = true;
current += char;
continue;
}

if (char === "[" || char === "{" || char === "(") depth++;
if (char === "]" || char === "}" || char === ")") depth--;

if (char === "," && depth === 0) {
result.push(current);
current = "";
continue;
}

current += char;
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Ballerina string literal escape sequence backslash quote

💡 Result:

In the Ballerina programming language, to include a literal backslash or a literal double quote within a double-quoted string, you must use specific escape sequences [1][2]. The supported single escape sequences for string literals are [1][3]: - \ represents a literal backslash character. - " represents a literal double quote character. Other standard escape sequences include \t (tab), \n (newline), and \r (carriage return) [1][2]. Additionally, Ballerina supports numeric Unicode escapes using the \u{CodePoint} syntax, where CodePoint is a hexadecimal numeral [1][4][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
fd -a 'rawValueUtils\.ts$' . || true

echo "== file outline =="
ast-grep outline 'workspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.ts' --view expanded || true

echo "== relevant source =="
cat -n 'workspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.ts' | sed -n '1,140p'

echo "== references/usages =="
rg -n "stringToRawArrayElements|rawValueUtils" -S .

Repository: wso2/vscode-extensions

Length of output: 10155


🌐 Web query:

Ballerina string literal escape sequence backslash quote

💡 Result:

In Ballerina, string literals are enclosed in double quotes (") and support specific escape sequences [1][2][3]. To include a literal backslash or a double quote within a string, you must use the following escape sequences [1][2][3]: - \: Represents a literal backslash character [1][2][3]. - ": Represents a literal double quote character [1][2][3]. These belong to the category of "StringSingleEscape" sequences, which also include common escapes such as \t (tab), \n (newline), and \r (carriage return) [1][2][3]. Additionally, Ballerina supports numeric Unicode escapes using the syntax \u{HexDigits} (e.g., \u{1F600}) [1][4][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== deterministic behavior probe for rawValueUtils parser path =="
node - <<'JS'
function stringToRawArrayElements(input) {
    const s = input.trim().slice(1, -1);
    if (s === "") return [];
    const result = [];
    let current = "";
    let depth = 0;
    let inString = false;
    let inTemplate = false;
    let interpolationDepth = 0;
    for (let i = 0; i < s.length; i++) {
        const char = s[i];
        const prev = s[i - 1];
        if (inString) {
            if (char === '"' && prev !== "\\") inString = false;
            current += char;
            continue;
        }
        if (interpolationDepth > 0) {
            if (char === '"') inString = true;
            else if (char === "{") interpolationDepth++;
            else if (char === "}") interpolationDepth--;
            current += char;
            continue;
        }
        if (inTemplate) {
            if (char === "{" && prev === "$") interpolationDepth++;
            else if (char === "`") inTemplate = false;
            current += char;
            continue;
        }
        if (char === "`") {
            inTemplate = true;
            current += char;
            continue;
        }
        if (char === '"' && prev !== "\\") {
            inString = true;
            current += char;
            continue;
        }
        if (char === "[" || char === "{" || char === "(") depth++;
        if (char === "]" || char === "}" || char === ")") depth--;
        if (char === "," && depth === 0) {
            result.push(current);
            current = "";
            continue;
        }
        current += char;
    }
    result.push(current);
    return result;
}

for (const input of ['["a\\", b]', '["a\\\\", b]', '[a, b]']) {
    console.log(JSON.stringify(input), "=>", JSON.stringify(stringToRawArrayElements(input)));
}
JS

echo "== Ballerina docs sections mentioning StringSingleEscape/backslash in current/master docs =="
for url in "https://ballerina.io/spec/lang/master/#sec-string-literal" "https://ballerina.io/spec/lang/2023R1/#sec-string-literal"; do
  echo "-- $url"
  curl -sSL --max-time 20 "$url" | \
    grep -iE "StringSingleEscape|escape.*backslash|backslash|\\\\\\\\|\\\\\"" | head -20 || true
done

Repository: wso2/vscode-extensions

Length of output: 1433


Track quote escapes instead of relying on the previous character.

stringToRawArrayElements uses prev !== "\\" to decide whether " closes a string. In a valid Ballerina string such as "a\\", b, the closing quote follows a literal backslash escape, so inString stays true and the separator is merged into the first element. Use an explicit escape state so \\ does not escape the next quote.

🤖 Prompt for 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.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.ts`
around lines 46 - 107, Update stringToRawArrayElements to track an explicit
escape state while scanning quoted strings, rather than determining quote
closure solely from the previous character. Ensure escaped backslashes do not
escape the following quote, so valid separators after strings such as "a\\", b
are recognized correctly; preserve existing template and nesting behavior.

Comment on lines +118 to +124
export function buildStringArray(elements: FormField[]): string {
if (typeof elements === "string") return elements;
const parts = elements.map(el => {
return ((el.value as string) ?? "").trim();
});
return `[${parts.join(", ")}]`;
}

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Guard against non-string element values before calling .trim().

FormField.value is typed string | any, so el.value can legitimately hold a non-string value (for example a number or boolean) for a repeatable array element. (el.value as string) ?? "" is a compile-time-only cast; at runtime, if el.value is 0, false, or another non-string value, .trim() throws because these types have no .trim() method. This function runs on handleModeSwitchValueChange in FormArrayEditor.tsx, so a numeric or boolean array element would crash the mode switch instead of degrading gracefully.

Coerce with String() before trimming so any primitive value is handled safely.

🛡️ Proposed fix to coerce non-string values safely
     const parts = elements.map(el => {
-        return ((el.value as string) ?? "").trim();
+        return String(el.value ?? "").trim();
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function buildStringArray(elements: FormField[]): string {
if (typeof elements === "string") return elements;
const parts = elements.map(el => {
return ((el.value as string) ?? "").trim();
});
return `[${parts.join(", ")}]`;
}
export function buildStringArray(elements: FormField[]): string {
if (typeof elements === "string") return elements;
const parts = elements.map(el => {
return String(el.value ?? "").trim();
});
return `[${parts.join(", ")}]`;
}
🤖 Prompt for 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.

In
`@workspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.ts`
around lines 118 - 124, Update buildStringArray to coerce each el.value to a
string before trimming, rather than relying on the compile-time cast. Preserve
the existing empty-value fallback and array formatting while ensuring numeric,
boolean, and other primitive values cannot cause .trim() to throw.

*/

const TOML_STRING_PATTERN = /^"([^"\\\n\r]|\\(["\\bfnrt]|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))*"$/;
const TOML_INVALID_ESCAPE_PATTERN = /^(?:[^\\]|\\(?:["\\bfnrt]|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))*\\([\s\S]?)/;

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

node <<'EOF'
const pattern = /^(?:[^\\]|\\(?:["\\bfnrt]|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))*\\([\s\S]?)/;

for (const value of ["\\u12G4", "\\u123", "\\q"]) {
    const match = pattern.exec(value);
    console.log(JSON.stringify({ value, captured: match ? match[1] : null }));
}
EOF

Repository: wso2/vscode-extensions

Length of output: 260


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/utils.ts"

if [ ! -f "$file" ]; then
  echo "missing: $file"
  git ls-files | grep -F 'utils.ts' | sed -n '1,120p'
  exit 0
fi

echo "== file stats =="
wc -l "$file"

echo "== relevant sections =="
sed -n '1,40p' "$file"
sed -n '110,175p' "$file"

echo "== tests/usages around TOML_INVALID_ESCAPE_PATTERN =="
rg -n "TOML_INVALID_ESCAPE_PATTERN|Invalid escape sequence|Invalid .*escape|malformed|\\u[0-9a-fA-F]" workspaces/ballerina/ballerina-visualizer -S || true

Repository: wso2/vscode-extensions

Length of output: 4677


Report the complete malformed Unicode escape.

TOML_INVALID_ESCAPE_PATTERN captures only one character after \. For "\u12G4" and "\u123", the error reports Invalid escape sequence '\u' and omits the invalid or missing digits. Capture the malformed \u or \U payload and add regression tests.

🤖 Prompt for 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.

In
`@workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/utils.ts`
at line 20, The TOML_INVALID_ESCAPE_PATTERN currently captures only the first
character of malformed Unicode escapes; update it to capture the complete
malformed \u or \U payload, including invalid or missing digits, so diagnostics
report the full sequence. Add regression tests covering inputs such as "\u12G4"
and "\u123" and assert that the reported invalid escape includes the complete
malformed payload.

Comment on lines +157 to +166
case 'string': {
if (TOML_STRING_PATTERN.test(trimmedValue)) {
return '';
}
const invalidEscape = TOML_INVALID_ESCAPE_PATTERN.exec(trimmedValue.replace(/^"([\s\S]*)"$/, '$1'));
if (invalidEscape) {
return `Invalid escape sequence '\\${invalidEscape[1]}' in the string value.`;
}
return 'Enter a valid string value.';
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve detailed errors for union types.

When trimmedType contains |, Lines 123-128 discard the Invalid escape sequence ... result and return Enter a valid value for ${type}.. A malformed value such as "bad\q" with type string|int therefore does not show the new diagnostic. Propagate a detailed error from the failed string alternative before falling back to the generic union error.

🧰 Tools
🪛 OpenGrep (1.26.0)

[ERROR] 161-161: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🤖 Prompt for 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.

In
`@workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/utils.ts`
around lines 157 - 166, Update the union-type validation flow around the string
alternative so an `Invalid escape sequence ...` result from the string case is
propagated before returning the generic `Enter a valid value for ${type}.`
message. Preserve the existing generic fallback for union values without a
detailed string-validation error, using the detailed result produced by the
string branch.

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.

8 participants