Automatic Sync: Merge changes from stable/ballerina to main - #2454
Automatic Sync: Merge changes from stable/ballerina to main#2454choreo-cicd wants to merge 41 commits into
Conversation
Fix trivy vulnerability issue
Fix the blueChip rendering issue for the rc1
Fix the trivy vulnerability
Fix vulnerability
Fix e2e tests with the vscode update
Fix vulnerabilities
Revert "Fix vulnerabilities"
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"
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>
Fix trivy issues
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"
📝 WalkthroughWalkthroughThe 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. ChangesDependency security updates
Build token wiring
ICP support gating
Artifact recovery
Raw array editing
End-to-end test stability
Validation and support messaging
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
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
⚔️ Resolve merge conflicts 💡
🧪 Generate unit tests (beta)
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.jsonFile 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. Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (2)
common/autoinstallers/rush-plugins/pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlcommon/config/rush/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (33)
.github/actions/build/action.yml.trivyignorecommon/autoinstallers/rush-plugins/package.jsoncommon/config/rush/.pnpmfile.cjscommon/config/rush/pnpm-config.jsonworkspaces/api-designer/api-designer-extension/package.jsonworkspaces/ballerina/ballerina-core/src/state-machine-types.tsworkspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/run-concurrent/run-concurrent.spec.tsworkspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/run-conflict/run-conflict.spec.tsworkspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/helpers/setup.tsworkspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/helpers/sidebar.tsworkspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/utils/pages/ProjectExplorer.tsworkspaces/ballerina/ballerina-extension/package.jsonworkspaces/ballerina/ballerina-extension/src/RPCLayer.tsworkspaces/ballerina/ballerina-extension/src/extension.tsworkspaces/ballerina/ballerina-extension/src/features/ai/utils/ai-client.tsworkspaces/ballerina/ballerina-extension/src/features/bi/activator.tsworkspaces/ballerina/ballerina-extension/src/features/icp/activator.tsworkspaces/ballerina/ballerina-extension/src/rpc-managers/icp-service/rpc-manager.tsworkspaces/ballerina/ballerina-extension/src/utils/config.tsworkspaces/ballerina/ballerina-extension/src/utils/project-artifacts.tsworkspaces/ballerina/ballerina-side-panel/package.jsonworkspaces/ballerina/ballerina-side-panel/src/components/editors/FormArrayEditor.tsxworkspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.tsworkspaces/ballerina/ballerina-side-panel/src/components/editors/rawValueUtils.tsworkspaces/ballerina/ballerina-side-panel/src/components/editors/utils.tsworkspaces/ballerina/ballerina-side-panel/test/rawValueUtils.test.mjsworkspaces/ballerina/ballerina-visualizer/src/MainPanel.tsxworkspaces/ballerina/ballerina-visualizer/src/views/AIPanel/components/AIChat/index.tsxworkspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/utils.tsworkspaces/ballerina/ballerina-visualizer/src/views/BI/PackageOverview/index.tsxworkspaces/ballerina/ballerina-visualizer/src/views/BI/WorkspaceOverview/index.tsxworkspaces/mi/mi-extension/package.json
| "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" |
There was a problem hiding this comment.
🔒 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.
| 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. | ||
| } |
There was a problem hiding this comment.
🩺 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.
| 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; | ||
| } |
There was a problem hiding this comment.
🎯 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.
| // The orphan filter only applies to interpolation-based editors (e.g. prompt/template) | ||
| const hasInterpolation = tokens.some(token => token.type === TokenType.START_EVENT); |
There was a problem hiding this comment.
🎯 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' || trueRepository: 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/ChipExpressionEditorRepository: 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))
PYRepository: 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.
| 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; | ||
| } |
There was a problem hiding this comment.
🎯 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:
- 1: https://ballerina.io/spec/lang/2023R1/
- 2: https://ballerina.io/spec/lang/master/
- 3: https://ballerina.io/spec/lang/2024R1/
- 4: https://github.com/ballerina-platform/ballerina-distribution/blob/v2201.2.0/examples/strings/strings.bal
- 5: https://ballerina.io/spec/lang/2020R1/
🏁 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:
- 1: https://ballerina.io/spec/lang/2023R1/
- 2: https://ballerina.io/spec/lang/2024R1/
- 3: https://ballerina.io/spec/lang/master/
- 4: https://github.com/ballerina-platform/ballerina-distribution/blob/v2201.2.0/examples/strings/strings.bal
🏁 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
doneRepository: 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.
| 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(", ")}]`; | ||
| } |
There was a problem hiding this comment.
🩺 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.
| 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]?)/; |
There was a problem hiding this comment.
🎯 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 }));
}
EOFRepository: 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 || trueRepository: 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.
| 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.'; | ||
| } |
There was a problem hiding this comment.
🎯 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.
This PR syncs changes from stable/ballerina to the main branch.
Automated PR created by GitHub Actions.
Summary by CodeRabbit
New Features
Bug Fixes
Updates