Automatic Sync: Merge changes from stable/mi to main#2398
Automatic Sync: Merge changes from stable/mi to main#2398choreo-cicd wants to merge 151 commits into
Conversation
Replace VALID_FILE_EXTENSIONS / VALID_SPECIAL_FILE_NAMES with BLOCKED_BINARY_EXTENSIONS so the agent can read/write any text file (including extensionless ones like Dockerfile, Makefile, .gitignore) while still blocking archives, executables, office docs, images, etc. Shell sandbox now enforces the same deny-list on mutation paths. The @-mention picker keeps its own short UX allow-list, decoupled from the security gate. Also enable XML validation for .dbs data services.
Trim filePath in getReadFileKind() to keep classification consistent with validateReadableFilePath(), and update shell sandbox error message to accurately describe all mutation types (write/edit/delete/rename).
Loads a root-level AGENTS.md (CLAUDE.md / Cursor convention) as a tracked context block. Re-injected only on content drift via the existing session-context hash system, so it does not waste tokens every turn. Files over 30 KB are truncated before being shipped to the model. The block carries an explicit truncation banner so the agent knows context is missing (and can file_read the tail on demand), and a persistent in-chat warning segment tells the user. Truncation warnings fire only when the block is actually being injected, so an unchanged large file does not re-warn each turn.
- agent.ts: make `saveAgentsMdWarning` failure non-fatal. The live event still fires so the user sees the warning this turn; only the JSONL replay across reconnects is sacrificed on persistence failure. - prompt.ts: neutralize embedded `<system-reminder>` / `<user_query>` tags in user-authored AGENTS.md so they can't break out of the surrounding envelope. Replaces the angle brackets with U+27E8 / U+27E9. - prompt.ts: fix the `SessionContextBlockHashes.agentsMd` doc comment to describe what the code actually hashes (surfaced bytes + truncation metadata) instead of the old "full untruncated raw bytes" claim. - AIChatFooter.tsx: splice the warning before the optimistic streaming placeholder. Appending at the end displaced the placeholder, causing subsequent content_block / thinking_* events to land in the warning bubble instead of the assistant message. - eventToMessageConverter.ts: drop `(event as any)` cast now that `warningMessage` is a typed field on AgentEvent / ChatHistoryEvent.
Fix trivy detected vulnerabilities
Support the startOnLoad attribute for tasks in MI 4.1.0
Instruct agent-mode to flip pom.xml <packaging> to jar and declare synapse-core when creating a class mediator, otherwise the CApp ships without the compiled jar and deployment silently fails. Fixes wso2/product-integrator#1631
file_write and file_edit now append a <system-reminder> to the tool result whenever the touched file is a class mediator java source (src/main/java/**/*.java), telling the agent to verify root pom.xml packaging is "jar" and synapse-core is declared. The prompt-level guideline alone can be missed; a per-tool reminder makes it harder to skip. Related to wso2/product-integrator#1631
Read the project root pom.xml and skip the class mediator reminder when <packaging>jar</packaging> is already set, so the agent is not prompted to fix something that is already correct. When packaging is something else (typically the default "pom"), the reminder reports the current value to make the required change unambiguous.
Prepare for the MI 4.0.2 release
…ging Fix copilot-created class mediators not packed in CApp
- Clarify file_read offset/limit are line-based in AGENTS.md guidance - Use Math.ceil for KB rounding and improve truncation warning copy - Add aria-hidden to decorative warning icon - Dedup context_warning on panel reconnect/event replay
Mirror the POSIX shell sandbox check so the agent cannot mutate foo.jar, foo.dll, etc. via PowerShell on Windows.
Switch agent file tools to a binary deny-list
Fix trivy detected vulnerabilities
Sync latest changes from release/mi-4.0.2
Merge "micro-integrator-4.0.2" into "stable/mi"
Fix trivy detected vulnerabilities
Fix issues in the MI Extension
…tors, variables) Mirror of wso2/mi-vscode#1504 for the release/mi-4.1.1 line of this repo. Fixes the four classes of incorrect code reported in wso2/product-integrator#1640, all via the always-loaded agent-mode prompt/context guides, plus the Opus 4.7 -> 4.8 main-agent model swap. - Operator precedence: Synapse's grammar makes and/or bind tighter than comparison operators, so `a <= 0 or b > 10` mis-parses. Add a mandatory "parenthesize every comparison joined by and/or" rule to the expression guide, fix the contradictory "Key implication" narrative in synapse_expression_spec.ts, and correct all anti-pattern examples in the expression guide and edge-cases doc. - Platform limitations: add a scope rule to the main system prompt telling the agent to state what MI cannot do rather than fabricate invalid code. - Connector syntax: add a hard rule to never write a connector operation's XML without first calling get_connector_info mode='details', reinforced in connectors_guide.ts. - Uninitialized variables: add a declare-before-use rule to the variable mediator section and a WRONG/CORRECT example in synapse_edge_cases.ts. - Defer cross-file reference checks out of per-file auto-validation: add an opt-in skipCrossFileValidation flag to synapse/codeDiagnostic (XmlCode + validateXmlFile); file_write/file_edit set it so their per-file pass omits cross-file reference checks, validate_code leaves it off. Optional and ignored by language servers that don't support it. - Model: swap claude-opus-4-7 -> claude-opus-4-8 for the 'opus' main-agent preset (direct + Bedrock inference profile), with UI label and comment updates. Refs: wso2/product-integrator#1640 Mirrors: wso2/mi-vscode#1504
…ails-1640 Fix agent-mode codegen guardrails (operator precedence, scope, connectors, variables)
Mirror of wso2/mi-vscode#1515 for the release/mi-4.1.1 line of this repo. The MI Copilot proxy blocks Opus models and returns a 400 with an explanatory body, but the chat error card only showed the SDK's generic status text, and WSO2 users could still select Opus in Settings. Settings (WSO2/MI_INTEL login only): - Disable both the Main Agent and Sub-Agent model switches (greyed out) with a note: "Sign in with your own Anthropic API key or AWS Bedrock to change models." BYOK (Anthropic key / Bedrock) is unaffected. - The Main switch always shows the non-Opus default; the high-intelligence warning is suppressed on the plan. Backend: - Clamp the main agent to Sonnet for MI_INTEL when an 'opus' preset carried over from a prior BYOK session, so it can't 400 every turn. Custom model IDs are left untouched. Error surfacing: - Add getDisplayErrorMessage() which extracts the upstream provider/proxy message from APICallError responseBody/data (walking the cause chain) instead of the bare HTTP status text, and wire it into the agent's stream 'error' path, execution catch, and the rpc-manager fallback catch. Mirrors: wso2/mi-vscode#1515
Add support to the binds-to attribute in APIs
Fix back button functionality issue
Mirror the review fixes applied to the mi-vscode PR so both repos carry an identical change set: stream_guard.ts: - Extract shared extractProviderErrorMessageFromBody() that handles APICallError.data as a raw string, surfaces JSON-quoted string bodies, and guards JSON.parse against oversized bodies (MAX_PARSEABLE_BODY_LENGTH) on the already-failing path. agent.ts: - Prefer abortReason over the caught error when building the user-facing message, so watchdog-wrapped errors keep the upstream provider detail. SettingsPanel.tsx / AICodeGenerator.tsx: - Add a byokResolved flag; gate model-switch locking on it and keep the controls neutral (disabled, no lock note, no warning) while resolution is pending. Reset byokResolved before each lookup and settle it on the failure path so the UI can't leak stale state or hang pending. - Make Reset to defaults respect the locked plan: on MI Copilot it no longer rewrites the (locked) model presets, closing the hidden model-switch path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AICodeGenerator.tsx: - Clear isByok/isAwsBedrock (not just byokResolved) and run the re-gate before the rpcClient guard, so a failed or rpcClient-less lookup can't settle with a prior session's stale auth flags and wrongly unlock the model controls. SettingsPanel.tsx: - Use modelControlsDisabled (locked plan OR pending resolution) instead of isMiCopilotPlan for both handleResetDefaults and isDefault, so Reset to defaults can't rewrite presets before the plan is known. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…y-errors Lock model switching on WSO2 plan and surface proxy error messages
Merge "micro-integrator-4.1.1" into "stable/mi"
|
|
📝 WalkthroughWalkthroughAdds MCP Server artifact support to the MI extension (utilities, RPC methods, UI forms, project explorer integration), injects project ChangesDependency Version Bumps
MI Extension Features and Fixes
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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.1)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 91: End of file expected; Line 94: End of file expected; Line 96: JSON standard does not allow comments.; Line 108: End of file expected; Line 108: End of file expected; Line 109: Expected a property but instead found '// "ignoreMissing": [" ... [truncated 344 characters] ... an object, or a literal but instead found '// "fsevents"'.; Line 154: End of file expected; Line 155: End of file expected; Line 158: JSON standard does not allow comments.; Line 170: End of file expected; Line 170: End of file expected; Line 171: Expected a property but instead found '// "request": "*"'.; Line 170: End of file expected; Line 171: End of file expected; Line 175: JSON standard does not allow comments.; Line 182: End of file expected; Line 182: End of file expected; Line 182: End of file expected; Line 182: End of file expected; Line 184: JSON standard does not allow comments.; Line 196: End of file expected; Line 196: End of file expected; Line 197: Expected a property but instead found '// "dependencies": {'.; Line 196: End of file expected; Line 197: 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: 20
🧹 Nitpick comments (4)
workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts (1)
6898-6914: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffReuse the shared YAML/candidate-resolution logic.
This block re-implements the candidate-filename derivation already present in
buildInputSchemasForAPITools(mcp-server-utils.ts) and callsrequire("yaml")inside the loop. Consider extracting a shared helper (e.g.readApiSpecForOperation) inmcp-server-utils.tsand hoisting theparseimport to module scope to avoid duplication and repeatedrequirecalls.🤖 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/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts` around lines 6898 - 6914, This block duplicates the YAML candidate resolution and parsing logic already used in buildInputSchemasForAPITools, so refactor it to reuse a shared helper such as readApiSpecForOperation from mcp-server-utils.ts. Move the candidate-name derivation and file loading/parsing into that helper, and hoist the yaml parse import to module scope instead of calling require("yaml") inside the loop. Update the description-building path here to call the shared helper and use its returned spec before extractOperationDescription.workspaces/mi/mi-core/src/rpc-types/mi-visualizer/types.ts (1)
549-574: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueInconsistent
inputSchemaoptionality across the union.
APITool.inputSchemais optional (Line 563) whileSequenceTool.inputSchemais required (Line 573). Consumers ofUnifiedTool(e.g.ToolsList.saveEdit) treat the field uniformly viainputSchema ?? '', so the divergence is purely cosmetic at runtime but makes the contract ambiguous. Consider aligning both to the same optionality.🤖 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/mi/mi-core/src/rpc-types/mi-visualizer/types.ts` around lines 549 - 574, The UnifiedTool contract has inconsistent inputSchema optionality between APITool and SequenceTool, which makes the shape ambiguous for consumers like ToolsList.saveEdit that treat it the same way. Update the APITool and SequenceTool definitions in the mi-visualizer types so inputSchema has the same optionality on both variants, and keep the union consistent wherever UnifiedTool is defined or consumed.workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1)
391-413: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMissing
keyon the mapped wrapper<div>.The outer
.map(([key, value]) => ...)returns a<div>without akey, producing a React reconciliation warning. Use the iterationkey(artifact type) as the element key.♻️ Proposed change
- return (!hasOnlyUndefinedItems || hasConnections) && ( - <div> + return (!hasOnlyUndefinedItems || hasConnections) && ( + <div key={key}>🤖 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/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx` around lines 391 - 413, The outer element returned from the artifact-type `.map(([key, value]) => ...)` is missing a React `key`, which causes reconciliation warnings. Add the iteration `key` from this map to the wrapping `<div>` in `ProjectStructureView` so each artifact section is uniquely identified, and keep the inner `Entry` rendering unchanged.workspaces/mi/mi-visualizer/src/views/Forms/InboundEPform/ImportInboundConnector.tsx (1)
43-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
onImportSuccessprop is declared but never called.Success is signaled via
CLOSE_VIEWwithrecentIdentifier: "success"(whichInboundEPWizard.importInboundConnectorlistens for throughonParentPopupSubmitted), soonImportSuccessis unused dead surface. Either remove it fromImportInboundConnectorFormPropsor invoke it in the success branch to avoid confusing future callers.Also applies to: 60-81
🤖 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/mi/mi-visualizer/src/views/Forms/InboundEPform/ImportInboundConnector.tsx` around lines 43 - 47, The success callback in ImportInboundConnectorFormProps is currently dead surface because the success path already reports via CLOSE_VIEW with recentIdentifier: "success" and is handled by InboundEPWizard.importInboundConnector through onParentPopupSubmitted. Update ImportInboundConnector and its success branch to either remove onImportSuccess from ImportInboundConnectorFormProps if it is not needed, or call it explicitly where the import succeeds so the prop matches actual behavior.
🤖 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/autoinstallers/rush-plugins/package.json`:
- Line 11: The rush-plugins autoinstaller is pinned to undici 7.x even though
the repo still supports Node >=20.6.0, which can break supported installs below
20.18.1. Update the dependency in package.json for the rush-plugins
autoinstaller by either downgrading undici back to a 6.x release or raising the
repository’s Node engine floor to match undici 7.x, and make sure the chosen
option is reflected consistently where the Node support range is defined.
In `@common/config/rush/.pnpmfile.cjs`:
- Line 30: The lodash override is pinned to the wrong version, leaving the
security fix unapplied. Update the lodash version override in the .pnpmfile.cjs
dependency rewrite and the matching pnpm.overrides entry in package.json so both
use 4.18.1 instead of 4.18.0.
In `@workspaces/mi/mi-extension/src/ai-features/agent-mode/agents/main/prompt.ts`:
- Around line 583-606: The AGENTS.md loader in readAgentsMd currently follows
symlinks because it relies on statSync/readFileSync, which can let a workspace
inject arbitrary local file content into prompt context. Update readAgentsMd to
reject symlinked AGENTS.md entries by checking the file type with lstatSync (or
equivalent) before any read, and only proceed when the path is a regular file;
if you use realpath containment instead, ensure the resolved target stays within
the expected workspace. Keep the existing truncation logic intact after the
symlink check.
In
`@workspaces/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox_powershell.ts`:
- Around line 906-918: The binary deny-list check in the mutation handling for
shell sandboxing misses destructive git operations because `git rm` and `git mv`
are currently treated as plain `git` commands, so their path arguments never
become `mutationPathTokens`. Update `extractPathTokens()` or the mutation
classification path in `shell_sandbox_powershell.ts` to recognize the git
subcommand and mark `git rm`/`git mv` arguments as mutations, then ensure the
existing `blockedBinaryMutationPaths` logic and `hasBlockedBinaryExtension()`
check apply to those paths too.
In
`@workspaces/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox.ts`:
- Around line 1266-1268: The binary-path deny list in shell_sandbox.ts only
checks writePathTokens, so Git working-tree mutations like git rm and git mv can
slip through because the Git extractor currently only captures clone/init paths.
Update the Git argument extraction and blockedBinaryMutationPaths logic so
mutation commands also contribute their target paths to the same binary
extension check, using the existing shell parsing helpers and git-related
extraction code paths to locate the affected tokens.
In `@workspaces/mi/mi-extension/src/debugger/debugAdapter.ts`:
- Around line 554-574: Guard the async continuations in the debugger startup
flow so they do nothing after a disconnect. In `DebugAdapter` around the
`checkServerReadiness()` and `initializeDebugger()` promise chains, add the
existing `_isDisconnecting` check to both the success path and the catch path
before calling `openRuntimeServicesWebview`, setting
`extension.isServerStarted`, sending `miServerRunStateChanged`, showing errors,
or terminating. This keeps the post-start callbacks from running after
`disconnectRequest()` has already marked the session stopped.
In `@workspaces/mi/mi-extension/src/debugger/debugHelper.ts`:
- Line 242: The module-level activeBuildProcess is being cleared
unconditionally, which lets an older process exit wipe out a newer build handle.
Update the ownership check in debugHelper.ts so the exit/cleanup path only sets
activeBuildProcess to undefined when the exiting process is still the one
currently stored. Use the existing activeBuildProcess tracking in the
build-start and process-exit flow to compare identity (or a stable token/pid)
before clearing it.
- Around line 225-231: The build completion toast in debugHelper.ts should
ignore intentionally aborted builds instead of treating every nonzero close code
as a failure. Update abortBuildAndRun() and the buildProcess.on('close') handler
in DebugHelper to track when a build was killed during disconnect, then skip
both success/failure notifications for that aborted process. Use the existing
build process state in DebugHelper to distinguish normal exits from
abort-triggered SIGKILL closes before calling vscode.window.showErrorMessage.
In `@workspaces/mi/mi-extension/src/project-explorer/activate.ts`:
- Around line 486-490: The delete flow in the `activate` handler is passing the
raw `fileUri` into `deleteApiMetadata`, but that helper expects an `apiPath`
string and will fail when given a `Uri`. Update the call site in the
`item.contextValue === 'api'` branch to pass a path string instead, using
`fileUri.fsPath ?? fileUri`, so `deleteApiMetadata` can safely use
`path.basename` and `path.extname` without throwing.
In `@workspaces/mi/mi-extension/src/stateMachine.ts`:
- Around line 626-634: Do not remove the existing back target when handling
in-place view replacements. In `stateMachine.ts`, update the `event.data.type
=== EVENT_TYPE.REPLACE_VIEW` path so `history.pop()` is not called for
`REPLACE_VIEW`, and keep the existing `OPEN_VIEW`/`previousContext` logic intact
so `history` still preserves the prior navigation target for both form and
non-form views.
In `@workspaces/mi/mi-extension/src/util/mcp-server-utils.ts`:
- Around line 352-359: The sequence-tool XML generation in mcp-server-utils.ts
should not interpolate UnifiedTool.inputSchema directly into CDATA when it may
be undefined. Update the else branch that builds the <tool> block so
<inputSchema> uses the same safe fallback behavior as the API branch (for
example, an empty object/schema default or equivalent), ensuring tool.name,
tool.sequenceName, and tool.description remain unchanged while preventing
literal undefined from being emitted.
In `@workspaces/mi/mi-visualizer/src/Hooks.tsx`:
- Around line 54-56: The download-progress listener is being registered directly
in the Hooks.tsx hook body, so each render adds another
RpcClient.onDownloadProgress subscription and can duplicate setDownloadProgress
updates. Move the subscription setup into a useEffect in the same hook, and
update RpcClient.onDownloadProgress to return an unsubscribe/disposable handle
so the effect can clean it up on unmount or dependency changes.
In `@workspaces/mi/mi-visualizer/src/views/AIPanel/component/AIChatMessage.tsx`:
- Around line 344-345: `hasAnswerContent` in `AIChatMessage` is missing
`isContextWarning` from the system-only segment checks, so a warning-only
assistant message can incorrectly trigger the `FeedbackBar`. Update the segment
classification logic in `hasAnswerContent` to treat `segment.isContextWarning`
the same way as other system segments (like `isCompactSummary`), and keep the
rendering branch in `ContextWarningSegment` aligned with that behavior.
In `@workspaces/mi/mi-visualizer/src/views/Forms/InboundEPform/index.tsx`:
- Around line 226-232: The `handleAcceptDownload` flow is too fragile because
`localConnectors.find(...).id` can throw before `acceptDownload` runs if
`inboundOnconfirmation` is missing or no connector matches. Update
`handleAcceptDownload` to safely resolve the connector id with optional
chaining, check for a missing result, and return early or otherwise bail out
gracefully before calling `acceptDownload`; use the existing
`handleAcceptDownload`, `inboundOnconfirmation`, and `localConnectors` symbols
to keep the fix aligned with the current logic.
- Around line 175-184: The store connector lookup in selectStoreConnector
assumes localConnectors.find(...) always returns a match, so accessing .id can
throw before the requiresDownload fallback runs. Update selectStoreConnector to
safely handle a missing local connector by checking the find result before
reading id, and when no match exists, skip the RPC call and route directly to
requiresDownload(connector). Keep the existing happy path intact for matched
connectors.
In
`@workspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/CreateScratchToolDialog.tsx`:
- Around line 60-64: The `sanitizeToolName` helper in `CreateScratchToolDialog`
is only trimming underscores from one end because the final `replace(/^_+|_+$/,
'')` pattern is missing the global flag. Update that sanitization step so both
leading and trailing underscores are removed after normalization, ensuring
inputs like `!weather!` don’t produce a derived name with a trailing underscore
before `tool` is appended.
In
`@workspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/MCPServerToolsForm.tsx`:
- Around line 340-343: The sequenceName sanitization in MCPServerToolsForm
should trim both leading and trailing underscores correctly, since the current
replace call uses /^_+|_+$/ without a global flag and may leave a trailing
underscore when both ends match. Update the regex in the sequenceName
construction to remove all matched edge underscores in one pass, and keep the
logic around data.name, the chained replace calls, and the final '_tool' suffix
intact.
In `@workspaces/mi/mi-visualizer/src/views/Forms/RegistryResourceForm.tsx`:
- Around line 279-285: Normalize any backslashes to forward slashes in
handleRegistryPathPrefix() before doing startsWith/endsWith checks or building
the final resPath, so the duplicate lookup and recentIdentifier generation use
the same canonical path form as the later submission step. Update the path
assembly logic around createOptionValue, filePath, and resourceName/templateType
handling to compare and concatenate against a `/`-normalized value rather than
the raw Windows-style input, including the related block in the later section
noted by the comment.
In `@workspaces/mi/mi-visualizer/src/views/Forms/TaskForm.tsx`:
- Around line 267-269: The startOnLoad gate in TaskForm.tsx is using an exact
version match, which incorrectly disables the field on newer supported runtimes.
Update the logic around getProjectDetails, runtimeVersion, and
setIsStartOnLoadSupported to use a minimum-version comparison instead of
compareVersions(...) === 0, so 4.1.0 and later keep the field enabled and
existing startOnLoad values continue to be preserved when saving tasks.
In `@workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx`:
- Around line 310-325: Replace the native confirmation in deleteMCPServer with a
VS Code modal confirmation flow, since window.confirm may not render in
webviews. Update deleteMCPServer to await an extension-host-backed
showWarningMessage call with { modal: true } before invoking
rpcClient.getMiDiagramRpcClient().deleteArtifact for inboundEndpoint.path and
localEntry.path, and keep the delete logic behind the modal result.
---
Nitpick comments:
In `@workspaces/mi/mi-core/src/rpc-types/mi-visualizer/types.ts`:
- Around line 549-574: The UnifiedTool contract has inconsistent inputSchema
optionality between APITool and SequenceTool, which makes the shape ambiguous
for consumers like ToolsList.saveEdit that treat it the same way. Update the
APITool and SequenceTool definitions in the mi-visualizer types so inputSchema
has the same optionality on both variants, and keep the union consistent
wherever UnifiedTool is defined or consumed.
In `@workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts`:
- Around line 6898-6914: This block duplicates the YAML candidate resolution and
parsing logic already used in buildInputSchemasForAPITools, so refactor it to
reuse a shared helper such as readApiSpecForOperation from mcp-server-utils.ts.
Move the candidate-name derivation and file loading/parsing into that helper,
and hoist the yaml parse import to module scope instead of calling
require("yaml") inside the loop. Update the description-building path here to
call the shared helper and use its returned spec before
extractOperationDescription.
In
`@workspaces/mi/mi-visualizer/src/views/Forms/InboundEPform/ImportInboundConnector.tsx`:
- Around line 43-47: The success callback in ImportInboundConnectorFormProps is
currently dead surface because the success path already reports via CLOSE_VIEW
with recentIdentifier: "success" and is handled by
InboundEPWizard.importInboundConnector through onParentPopupSubmitted. Update
ImportInboundConnector and its success branch to either remove onImportSuccess
from ImportInboundConnectorFormProps if it is not needed, or call it explicitly
where the import succeeds so the prop matches actual behavior.
In `@workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx`:
- Around line 391-413: The outer element returned from the artifact-type
`.map(([key, value]) => ...)` is missing a React `key`, which causes
reconciliation warnings. Add the iteration `key` from this map to the wrapping
`<div>` in `ProjectStructureView` so each artifact section is uniquely
identified, and keep the inner `Entry` rendering unchanged.
🪄 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
Run ID: e6d3470f-c23f-4953-8f19-85eb45897d2c
⛔ 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 (144)
common/autoinstallers/rush-plugins/package.jsoncommon/config/rush/.pnpmfile.cjscommon/config/rush/pnpm-config.jsonpackage.jsonworkspaces/api-designer/api-designer-extension/package.jsonworkspaces/api-designer/api-designer-visualizer/package.jsonworkspaces/ballerina/ballerina-extension/package.jsonworkspaces/ballerina/ballerina-low-code-diagram/package.jsonworkspaces/ballerina/ballerina-side-panel/package.jsonworkspaces/ballerina/ballerina-visualizer/package.jsonworkspaces/ballerina/bi-diagram/package.jsonworkspaces/ballerina/component-diagram/package.jsonworkspaces/ballerina/graphql/package.jsonworkspaces/ballerina/persist-layer-diagram/package.jsonworkspaces/ballerina/sequence-diagram/package.jsonworkspaces/ballerina/trace-visualizer/package.jsonworkspaces/ballerina/type-diagram/package.jsonworkspaces/choreo/choreo-extension/package.jsonworkspaces/choreo/choreo-webviews/package.jsonworkspaces/mi/mi-core/src/rpc-types/agent-mode/types.tsworkspaces/mi/mi-core/src/rpc-types/mi-diagram/index.tsworkspaces/mi/mi-core/src/rpc-types/mi-diagram/rpc-type.tsworkspaces/mi/mi-core/src/rpc-types/mi-diagram/types.tsworkspaces/mi/mi-core/src/rpc-types/mi-visualizer/index.tsworkspaces/mi/mi-core/src/rpc-types/mi-visualizer/rpc-type.tsworkspaces/mi/mi-core/src/rpc-types/mi-visualizer/types.tsworkspaces/mi/mi-core/src/state-machine-types.tsworkspaces/mi/mi-diagram/package.jsonworkspaces/mi/mi-diagram/src/components/Diagram.tsxworkspaces/mi/mi-diagram/src/components/Form/Keylookup/Keylookup.tsxworkspaces/mi/mi-diagram/src/components/nodes/BaseNodeModel.tsworkspaces/mi/mi-diagram/src/components/sidePanel/connections/index.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/index.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/mediators/List.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/mediators/Mediator.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/mediators/index.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/tryout/SetPayloads.tsxworkspaces/mi/mi-extension/CHANGELOG.mdworkspaces/mi/mi-extension/package.jsonworkspaces/mi/mi-extension/src/RPCLayer.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/agents/main/agent.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/agents/main/prompt.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/agents/main/system.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/attachment-utils.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/chat-history-manager.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/context/connectors_guide.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/context/synapse-core/synapse_edge_cases.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/context/synapse-core/synapse_expression_spec.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/context/synapse_expression_guide.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/context/synapse_guide.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/context/synapse_guide_old.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/stream_guard.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/tools/file_tools.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/tools/lsp_tools.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox_powershell.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/tools/types.tsworkspaces/mi/mi-extension/src/ai-features/agent-mode/tools/validation-utils.tsworkspaces/mi/mi-extension/src/ai-features/auth.tsworkspaces/mi/mi-extension/src/ai-features/connection.tsworkspaces/mi/mi-extension/src/ai-features/copilot/message-utils.tsworkspaces/mi/mi-extension/src/constants/index.tsworkspaces/mi/mi-extension/src/debugger/activate.tsworkspaces/mi/mi-extension/src/debugger/debugAdapter.tsworkspaces/mi/mi-extension/src/debugger/debugHelper.tsworkspaces/mi/mi-extension/src/lang-client/ExtendedLanguageClient.tsworkspaces/mi/mi-extension/src/project-explorer/activate.tsworkspaces/mi/mi-extension/src/project-explorer/project-explorer-provider.tsworkspaces/mi/mi-extension/src/rpc-managers/agent-mode/rpc-manager.tsworkspaces/mi/mi-extension/src/rpc-managers/ai-features/rpc-handler.tsworkspaces/mi/mi-extension/src/rpc-managers/ai-features/rpc-manager.tsworkspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-handler.tsworkspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.tsworkspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.tsworkspaces/mi/mi-extension/src/stateMachine.tsworkspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/Automation.tsworkspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/ClassMediator.tsworkspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ProjectExplorer.tsworkspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/UnitTest.tsworkspaces/mi/mi-extension/src/test/e2e-playwright-tests/connectorTests/connector.spec.tsworkspaces/mi/mi-extension/src/test/e2e-playwright-tests/test.list.tsworkspaces/mi/mi-extension/src/util/fileOperations.tsworkspaces/mi/mi-extension/src/util/mcp-server-utils.tsworkspaces/mi/mi-extension/src/util/template-engine/mustach-templates/tasks.tsworkspaces/mi/mi-extension/src/visualizer/activate.tsworkspaces/mi/mi-rpc-client/src/rpc-clients/mi-diagram/rpc-client.tsworkspaces/mi/mi-rpc-client/src/rpc-clients/mi-visualizer/rpc-client.tsworkspaces/mi/mi-visualizer/package.jsonworkspaces/mi/mi-visualizer/src/Hooks.tsxworkspaces/mi/mi-visualizer/src/MainPanel.tsxworkspaces/mi/mi-visualizer/src/PopupPanel.tsxworkspaces/mi/mi-visualizer/src/components/AuthenticationDialog/AuthenticationDialog.tsxworkspaces/mi/mi-visualizer/src/components/AuthenticationDialog/useAuthentication.tsworkspaces/mi/mi-visualizer/src/components/NavigationBar/HierachicalPath.tsxworkspaces/mi/mi-visualizer/src/components/View/ViewContent.tsxworkspaces/mi/mi-visualizer/src/constants/index.tsworkspaces/mi/mi-visualizer/src/utils/form.tsworkspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/api.tsworkspaces/mi/mi-visualizer/src/views/AIPanel/component/AIChatFooter.tsxworkspaces/mi/mi-visualizer/src/views/AIPanel/component/AIChatMessage.tsxworkspaces/mi/mi-visualizer/src/views/AIPanel/component/AICodeGenerator.tsxworkspaces/mi/mi-visualizer/src/views/AIPanel/component/ContextWarningSegment.tsxworkspaces/mi/mi-visualizer/src/views/AIPanel/component/MICopilotContext.tsxworkspaces/mi/mi-visualizer/src/views/AIPanel/component/SettingsPanel.tsxworkspaces/mi/mi-visualizer/src/views/AIPanel/constants.tsworkspaces/mi/mi-visualizer/src/views/AIPanel/utils.tsworkspaces/mi/mi-visualizer/src/views/AIPanel/utils/eventToMessageConverter.tsworkspaces/mi/mi-visualizer/src/views/AddArtifact/index.tsxworkspaces/mi/mi-visualizer/src/views/Diagram/InboundEndpoint.tsxworkspaces/mi/mi-visualizer/src/views/Diagram/Resource.tsxworkspaces/mi/mi-visualizer/src/views/Diagram/Task.tsxworkspaces/mi/mi-visualizer/src/views/Forms/APIform/index.tsxworkspaces/mi/mi-visualizer/src/views/Forms/Commons/index.tsxworkspaces/mi/mi-visualizer/src/views/Forms/ConnectionForm/ImportConnector.tsxworkspaces/mi/mi-visualizer/src/views/Forms/ConnectionForm/index.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/IDPConnectorForm/IdpConnectorSchemaGenerateForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/InboundEPform/ImportInboundConnector.tsxworkspaces/mi/mi-visualizer/src/views/Forms/InboundEPform/inboundConnectorForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/InboundEPform/index.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/AddAPIToolDialog.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/AddSequenceToolDialog.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/CreateScratchToolDialog.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/MCPServerToolsForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/ToolTypeSelector.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/ToolsList.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/index.tsxworkspaces/mi/mi-visualizer/src/views/Forms/MCPServerForm/styles.tsworkspaces/mi/mi-visualizer/src/views/Forms/ProxyServiceForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/RegistryResourceForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/ResourceForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/TaskForm.tsxworkspaces/mi/mi-visualizer/src/views/Forms/Tests/TestSuiteForm.tsxworkspaces/mi/mi-visualizer/src/views/Overview/ProjectInformation/index.tsxworkspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsxworkspaces/mi/mi-visualizer/src/views/Overview/index.tsxworkspaces/mi/mi-visualizer/src/views/ServiceDesigner/index.tsxworkspaces/mi/syntax-tree/src/syntax-tree-interfaces.tsworkspaces/wso2-platform/wso2-platform-extension/package.jsonworkspaces/wso2-platform/wso2-platform-webviews/package.json
💤 Files with no reviewable changes (1)
- workspaces/mi/mi-visualizer/src/views/Forms/ProxyServiceForm.tsx
| "minimatch": "3.1.5", | ||
| "brace-expansion": "1.1.13", | ||
| "undici": "6.24.0" | ||
| "undici": "7.28.0" |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
undici 7 minimum supported Node.js version
💡 Result:
The minimum supported Node.js version for the Undici 7.x release line is Node.js 20.18.1 [1][2][3]. The Undici project maintains an LTS-aligned support schedule for its major versions, and the 7.x branch explicitly requires Node.js ≥20.18.1 [1][2][3]. This requirement is documented in the project's official README and is enforced via the engines field in the package's configuration, which may cause installation warnings or errors in environments using older Node.js versions [2][4]. As of June 30, 2026, the 7.x series remains a supported maintenance line [5]. It is tested against Node.js versions 20, 22, and 24 [1][2][3].
Citations:
- 1: https://npmx.dev/package/undici/v/7.23.0
- 2: https://github.com/nodejs/undici/blob/main/README.md
- 3: https://www.npmjs.com/package/undici
- 4: Undici 7.10 requires Node >=20.18.1 cheeriojs/cheerio#4618
- 5: https://github.com/nodejs/undici/releases
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '== package.json ==\n'
sed -n '1,120p' common/autoinstallers/rush-plugins/package.json
printf '\n== node/runtime constraints ==\n'
rg -n --hidden --glob '!**/node_modules/**' '"engines"|nodeVersion|Node\.js|node ' \
package.json common rush.json rush-*.json .npmrc .nvmrc .node-version .tool-versions 2>/dev/null || true
printf '\n== files mentioning undici ==\n'
rg -n --hidden --glob '!**/node_modules/**' '"undici"|undici@|undici ' common package.json rush.json 2>/dev/null || trueRepository: wso2/vscode-extensions
Length of output: 3253
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '== root package.json (engines/volta/packageManager) ==\n'
python3 - <<'PY'
from pathlib import Path
import json
p = Path('package.json')
data = json.loads(p.read_text())
for k in ['engines', 'volta', 'packageManager', 'os', 'cpu']:
if k in data:
print(f'{k}: {data[k]}')
PY
printf '\n== rush.json node settings ==\n'
python3 - <<'PY'
from pathlib import Path
import json
p = Path('rush.json')
data = json.loads(p.read_text())
for k in ['nodeSupportedVersionRange', 'nodeSupportedVersionInstructions', 'pnpmVersion', 'rushVersion']:
if k in data:
print(f'{k}: {data[k]}')
PY
printf '\n== rush.json excerpt around node-related settings ==\n'
sed -n '1,120p' rush.jsonRepository: wso2/vscode-extensions
Length of output: 846
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '== rush.json lines 1-120 ==\n'
cat -n rush.json | sed -n '1,120p'
printf '\n== root package.json ==\n'
cat -n package.json | sed -n '1,140p'
printf '\n== CI / workflow node version references ==\n'
rg -n --hidden --glob '!**/node_modules/**' 'node-version|Node\.js|setup-node|actions/setup-node|20\.18|20\.19|22\.|24\.' .github common package.json rush.json 2>/dev/null || trueRepository: wso2/vscode-extensions
Length of output: 13786
Keep undici 6.x or raise the Node floor
undici 7.x requires Node >=20.18.1, but this repo still supports >=20.6.0 <23.0.0, so the autoinstaller can break on supported 20.6–20.18 installs. Either bump the repo’s Node range or stay on 6.x.
🤖 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/autoinstallers/rush-plugins/package.json` at line 11, The rush-plugins
autoinstaller is pinned to undici 7.x even though the repo still supports Node
>=20.6.0, which can break supported installs below 20.18.1. Update the
dependency in package.json for the rush-plugins autoinstaller by either
downgrading undici back to a 6.x release or raising the repository’s Node engine
floor to match undici 7.x, and make sure the chosen option is reflected
consistently where the Node support range is defined.
| if (deps['eslint']) deps['eslint'] = '^9.27.0'; | ||
| if (deps['fast-xml-parser']) deps['fast-xml-parser'] = '5.7.0'; | ||
| if (deps['esbuild']) deps['esbuild'] = '0.25.12'; | ||
| if (deps['lodash']) deps['lodash'] = '4.18.0'; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Pin lodash to 4.18.1, not 4.18.0.
lodash 4.18.1 ships a prototype-pollution fix for _.unset/_.omit (constructor/prototype path traversal, GHSA-f23m-r3pf-42rh). Pinning the override to exactly 4.18.0 leaves that hole unpatched, which defeats the security intent of this override block. The same 4.18.0 pin is present in the root package.json pnpm.overrides (line 21); update both.
🛡️ Proposed fix
- if (deps['lodash']) deps['lodash'] = '4.18.0';
+ if (deps['lodash']) deps['lodash'] = '4.18.1'; // security fix: prototype pollution in _.unset/_.omit (GHSA-f23m-r3pf-42rh)📝 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.
| if (deps['lodash']) deps['lodash'] = '4.18.0'; | |
| if (deps['lodash']) deps['lodash'] = '4.18.1'; // security fix: prototype pollution in _.unset/_.omit (GHSA-f23m-r3pf-42rh) |
🤖 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/.pnpmfile.cjs` at line 30, The lodash override is pinned
to the wrong version, leaving the security fix unapplied. Update the lodash
version override in the .pnpmfile.cjs dependency rewrite and the matching
pnpm.overrides entry in package.json so both use 4.18.1 instead of 4.18.0.
| function readAgentsMd(projectPath: string): { content: string; truncated: boolean; originalSize: number } | undefined { | ||
| const agentsMdPath = path.join(projectPath, 'AGENTS.md'); | ||
| if (!fs.existsSync(agentsMdPath)) { | ||
| return undefined; | ||
| } | ||
| try { | ||
| const stat = fs.statSync(agentsMdPath); | ||
| if (!stat.isFile()) { | ||
| return undefined; | ||
| } | ||
| const originalSize = stat.size; | ||
| if (originalSize <= AGENTS_MD_MAX_BYTES) { | ||
| const content = fs.readFileSync(agentsMdPath, 'utf8'); | ||
| return { content, truncated: false, originalSize }; | ||
| } | ||
| // Oversized — read only the first AGENTS_MD_MAX_BYTES bytes. Open as | ||
| // a file descriptor so we don't pull the whole file into memory just | ||
| // to slice it. | ||
| const fd = fs.openSync(agentsMdPath, 'r'); | ||
| try { | ||
| const buffer = Buffer.allocUnsafe(AGENTS_MD_MAX_BYTES); | ||
| const bytesRead = fs.readSync(fd, buffer, 0, AGENTS_MD_MAX_BYTES, 0); | ||
| const content = buffer.subarray(0, bytesRead).toString('utf8'); | ||
| return { content, truncated: true, originalSize }; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
tmp_dir="$(mktemp -d)"
secret_file="$(mktemp)"
echo "SECRET_DO_NOT_SEND" > "$secret_file"
ln -s "$secret_file" "$tmp_dir/AGENTS.md"
node - "$tmp_dir" <<'NODE'
const fs = require('fs');
const path = require('path');
const root = process.argv[2];
const file = path.join(root, 'AGENTS.md');
console.log({
statIsFile: fs.statSync(file).isFile(),
lstatIsFile: fs.lstatSync(file).isFile(),
isSymlink: fs.lstatSync(file).isSymbolicLink(),
contentRead: fs.readFileSync(file, 'utf8').trim(),
});
NODERepository: wso2/vscode-extensions
Length of output: 261
Do not follow symlinks when loading AGENTS.md.
statSync/readFileSync will traverse a symlinked AGENTS.md, so an untrusted workspace can point it at any readable local file and inject that content into prompt context. Skip symlinks or enforce realpath containment before reading.
🧰 Tools
🪛 ast-grep (0.44.0)
[warning] 594-594: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(agentsMdPath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
🤖 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/mi/mi-extension/src/ai-features/agent-mode/agents/main/prompt.ts`
around lines 583 - 606, The AGENTS.md loader in readAgentsMd currently follows
symlinks because it relies on statSync/readFileSync, which can let a workspace
inject arbitrary local file content into prompt context. Update readAgentsMd to
reject symlinked AGENTS.md entries by checking the file type with lstatSync (or
equivalent) before any read, and only proceed when the path is a regular file;
if you use realpath containment instead, ensure the resolved target stays within
the expected workspace. Keep the existing truncation logic intact after the
symlink check.
| const blockedBinaryMutationPaths = dedupe( | ||
| extractedPathTokens.mutationPathTokens.filter( | ||
| (token) => hasBlockedBinaryExtension(path.win32.basename(stripWrappingQuotes(token))) | ||
| ) | ||
| ); | ||
| if (blockedBinaryMutationPaths.length > 0) { | ||
| blocked = true; | ||
| reasons.push( | ||
| `Mutating binary file paths is blocked (write/edit/delete/rename; matches the file-tool deny-list). ` + | ||
| `Blocked path(s): ${blockedBinaryMutationPaths.join(', ')}. ` + | ||
| `Use directory-level operations (e.g. \`Remove-Item -Recurse dist\`) instead of targeting binary files by name.` | ||
| ); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify PowerShell analyzer coverage for external mutation commands and path extraction.
rg -n -C 4 'POWERSHELL_MUTATION_COMMANDS|mutationFromCommands|isMutationCommand|git|npm|pnpm|yarn|pip|mutationPathTokens' workspaces/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox_powershell.tsRepository: wso2/vscode-extensions
Length of output: 6723
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=workspaces/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox_powershell.ts
# Map the relevant symbols first.
ast-grep outline "$FILE" --view expanded >/tmp/ps_outline.txt || true
sed -n '1,220p' /tmp/ps_outline.txt
# Read the command-name and path-extraction related sections.
sed -n '430,640p' "$FILE"
echo '---'
sed -n '820,930p' "$FILE"Repository: wso2/vscode-extensions
Length of output: 16268
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=workspaces/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox_powershell.ts
# Inspect the analyzer flow that builds commandNames and segments.
sed -n '700,860p' "$FILE"
echo '---'
sed -n '860,1020p' "$FILE"Repository: wso2/vscode-extensions
Length of output: 12803
Track destructive git subcommands as mutations. git rm foo.jar / git mv foo.jar bar.jar are parsed as git, so their path arguments never reach mutationPathTokens and the binary deny-list check here won’t fire. Special-case git rm / git mv in extractPathTokens() or propagate the git subcommand into mutation classification.
🤖 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/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox_powershell.ts`
around lines 906 - 918, The binary deny-list check in the mutation handling for
shell sandboxing misses destructive git operations because `git rm` and `git mv`
are currently treated as plain `git` commands, so their path arguments never
become `mutationPathTokens`. Update `extractPathTokens()` or the mutation
classification path in `shell_sandbox_powershell.ts` to recognize the git
subcommand and mark `git rm`/`git mv` arguments as mutations, then ensure the
existing `blockedBinaryMutationPaths` logic and `hasBlockedBinaryExtension()`
check apply to those paths too.
| const blockedBinaryMutationPaths = writePathTokens.filter( | ||
| (token) => !hasDynamicShellExpansion(token) && hasBlockedBinaryExtension(path.basename(token)) | ||
| ); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Cover Git working-tree mutations in the binary-path block.
blockedBinaryMutationPaths only inspects writePathTokens, but the Git extractor above only records paths for clone/init. Commands like git rm lib/foo.jar or git mv foo.jar bar.jar are mutations, but their binary targets never reach this deny-list and can proceed via approval instead of being blocked.
🛡️ Proposed extraction coverage
if (subcommand === 'clone' && positionalArgs.length >= 2) {
writePaths.push(positionalArgs[positionalArgs.length - 1]);
} else if (subcommand === 'init' && positionalArgs.length >= 1) {
writePaths.push(positionalArgs[positionalArgs.length - 1]);
+ } else if (['rm', 'mv', 'restore', 'checkout'].includes(subcommand)) {
+ writePaths.push(
+ ...positionalArgs
+ .map((token) => stripWrappingQuotes(token))
+ .filter((token) => looksLikePathToken(token))
+ );
}Also applies to: 1295-1301
🤖 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/mi/mi-extension/src/ai-features/agent-mode/tools/shell_sandbox.ts`
around lines 1266 - 1268, The binary-path deny list in shell_sandbox.ts only
checks writePathTokens, so Git working-tree mutations like git rm and git mv can
slip through because the Git extractor currently only captures clone/init paths.
Update the Git argument extraction and blockedBinaryMutationPaths logic so
mutation commands also contribute their target paths to the same binary
extension check, using the existing shell parsing helpers and git-related
extraction code paths to locate the affected tokens.
| const sanitizeToolName = (raw: string): string => | ||
| raw.trim().toLowerCase() | ||
| .replace(/[^a-z0-9]/g, '_') | ||
| .replace(/_{2,}/g, '_') | ||
| .replace(/^_+|_+$/, ''); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Trailing underscores not stripped when both ends have underscores.
/^_+|_+$/ lacks the global flag, so replace only removes the first matching alternation. For a value that ends up with leading and trailing underscores after sanitization (e.g. "!weather!" → "_weather_"), only the leading underscores are removed, yielding "weather_" and ultimately a derived sequence name like weather__tool. Add the g flag so both ends are trimmed.
🐛 Proposed fix
- .replace(/^_+|_+$/, '');
+ .replace(/^_+|_+$/g, '');📝 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.
| const sanitizeToolName = (raw: string): string => | |
| raw.trim().toLowerCase() | |
| .replace(/[^a-z0-9]/g, '_') | |
| .replace(/_{2,}/g, '_') | |
| .replace(/^_+|_+$/, ''); | |
| const sanitizeToolName = (raw: string): string => | |
| raw.trim().toLowerCase() | |
| .replace(/[^a-z0-9]/g, '_') | |
| .replace(/_{2,}/g, '_') | |
| .replace(/^_+|_+$/g, ''); |
🤖 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/mi/mi-visualizer/src/views/Forms/MCPServerForm/CreateScratchToolDialog.tsx`
around lines 60 - 64, The `sanitizeToolName` helper in `CreateScratchToolDialog`
is only trimming underscores from one end because the final `replace(/^_+|_+$/,
'')` pattern is missing the global flag. Update that sanitization step so both
leading and trailing underscores are removed after normalization, ensuring
inputs like `!weather!` don’t produce a derived name with a trailing underscore
before `tool` is appended.
| const sequenceName = data.name.toLowerCase() | ||
| .replace(/[^a-z0-9]/g, '_') | ||
| .replace(/_{2,}/g, '_') | ||
| .replace(/^_+|_+$/, '') + '_tool'; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Missing global flag in trim regex.
/^_+|_+$/ without the g flag replaces only the first matched alternative. For a name that produces both leading and trailing underscores (e.g. _foo_), only the leading underscores are stripped, yielding foo__tool instead of foo_tool.
🐛 Proposed fix
- .replace(/^_+|_+$/, '') + '_tool';
+ .replace(/^_+|_+$/g, '') + '_tool';📝 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.
| const sequenceName = data.name.toLowerCase() | |
| .replace(/[^a-z0-9]/g, '_') | |
| .replace(/_{2,}/g, '_') | |
| .replace(/^_+|_+$/, '') + '_tool'; | |
| const sequenceName = data.name.toLowerCase() | |
| .replace(/[^a-z0-9]/g, '_') | |
| .replace(/^_+|_+$/g, '') + '_tool'; |
🤖 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/mi/mi-visualizer/src/views/Forms/MCPServerForm/MCPServerToolsForm.tsx`
around lines 340 - 343, The sequenceName sanitization in MCPServerToolsForm
should trim both leading and trailing underscores correctly, since the current
replace call uses /^_+|_+$/ without a global flag and may leave a trailing
underscore when both ends match. Update the regex in the sequenceName
construction to remove all matched edge underscores in one pass, and keep the
logic around data.name, the chained replace calls, and the final '_tool' suffix
intact.
| resPath = PATH_SEPARATORS.some(sep => resourceDirPath.startsWith(sep)) ? resPath + resourceDirPath.substring(1) : resPath + resourceDirPath; | ||
| if (createOptionValue) { | ||
| resPath.endsWith('/') ? resPath = resPath + getValues("resourceName") + getFileExtension(getValues('templateType')) | ||
| PATH_SEPARATORS.some(sep => resPath.endsWith(sep)) ? resPath = resPath + getValues("resourceName") + getFileExtension(getValues('templateType')) | ||
| : resPath = resPath + '/' + getValues("resourceName") + getFileExtension(getValues('templateType')); | ||
| } else { | ||
| const filename = getValues("filePath").split('/').pop(); | ||
| resPath.endsWith('/') ? resPath = resPath + filename : resPath = resPath + '/' + filename; | ||
| const filename = getValues("filePath").split(/[/\\]/).pop(); | ||
| PATH_SEPARATORS.some(sep => resPath.endsWith(sep)) ? resPath = resPath + filename : resPath = resPath + '/' + filename; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Normalize \ to / before path comparisons.
These helpers now keep internal backslashes, but handleRegistryPathPrefix() later canonicalizes the submitted path to /. On Windows that can make the duplicate check miss an existing resource/registry entry and produce a mismatched recentIdentifier.
Suggested fix
const formatResourcePath = (resourceDirPath: string) => {
+ const normalizedResourceDirPath = resourceDirPath.replace(/[\\]/g, '/');
let resPath = 'resources:';
- resPath = PATH_SEPARATORS.some(sep => resourceDirPath.startsWith(sep)) ? resPath + resourceDirPath.substring(1) : resPath + resourceDirPath;
+ resPath = normalizedResourceDirPath.startsWith('/') ? resPath + normalizedResourceDirPath.substring(1) : resPath + normalizedResourceDirPath;
if (createOptionValue) {
- PATH_SEPARATORS.some(sep => resPath.endsWith(sep)) ? resPath = resPath + getValues("resourceName") + getFileExtension(getValues('templateType'))
+ PATH_SEPARATORS.some(sep => resPath.endsWith(sep)) ? resPath = resPath + getValues("resourceName") + getFileExtension(getValues('templateType'))
: resPath = resPath + '/' + getValues("resourceName") + getFileExtension(getValues('templateType'));
} else {
- const filename = getValues("filePath").split(/[/\\]/).pop();
+ const filename = getValues("filePath").split(/[/\\]/).pop();
PATH_SEPARATORS.some(sep => resPath.endsWith(sep)) ? resPath = resPath + filename : resPath = resPath + '/' + filename;
}
return resPath;
}
const formatRegistryPath = (path: string) => {
+ const normalizedPath = path.replace(/[\\]/g, '/');
let regPath = '';
if (getValues("registryType") === 'gov') {
regPath = 'gov:';
} else {
regPath = 'conf:';
}
- PATH_SEPARATORS.some(sep => path.startsWith(sep)) ? regPath = regPath + path.substring(1) : regPath = regPath + path;
+ normalizedPath.startsWith('/') ? regPath = regPath + normalizedPath.substring(1) : regPath = regPath + normalizedPath;Also applies to: 297-303
🤖 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/mi/mi-visualizer/src/views/Forms/RegistryResourceForm.tsx` around
lines 279 - 285, Normalize any backslashes to forward slashes in
handleRegistryPathPrefix() before doing startsWith/endsWith checks or building
the final resPath, so the duplicate lookup and recentIdentifier generation use
the same canonical path form as the later submission step. Update the path
assembly logic around createOptionValue, filePath, and resourceName/templateType
handling to compare and concatenate against a `/`-normalized value rather than
the raw Windows-style input, including the related block in the later section
noted by the comment.
| const projectDetails = await rpcClient.getMiVisualizerRpcClient().getProjectDetails(); | ||
| const runtimeVersion = projectDetails.primaryDetails.runtimeVersion.value; | ||
| setIsStartOnLoadSupported(compareVersions(runtimeVersion, RUNTIME_VERSION_410) === 0); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Use a minimum-version check for startOnLoad.
This gate only enables the feature on exactly 4.1.0. On 4.1.1+, the form hides the field, Line 308 stops sending startOnLoad, and updating an existing task can drop the XML attribute even though the backend already parses and templates it.
Suggested fix
- setIsStartOnLoadSupported(compareVersions(runtimeVersion, RUNTIME_VERSION_410) === 0);
+ setIsStartOnLoadSupported(compareVersions(runtimeVersion, RUNTIME_VERSION_410) >= 0);📝 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.
| const projectDetails = await rpcClient.getMiVisualizerRpcClient().getProjectDetails(); | |
| const runtimeVersion = projectDetails.primaryDetails.runtimeVersion.value; | |
| setIsStartOnLoadSupported(compareVersions(runtimeVersion, RUNTIME_VERSION_410) === 0); | |
| const projectDetails = await rpcClient.getMiVisualizerRpcClient().getProjectDetails(); | |
| const runtimeVersion = projectDetails.primaryDetails.runtimeVersion.value; | |
| setIsStartOnLoadSupported(compareVersions(runtimeVersion, RUNTIME_VERSION_410) >= 0); |
🤖 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/mi/mi-visualizer/src/views/Forms/TaskForm.tsx` around lines 267 -
269, The startOnLoad gate in TaskForm.tsx is using an exact version match, which
incorrectly disables the field on newer supported runtimes. Update the logic
around getProjectDetails, runtimeVersion, and setIsStartOnLoadSupported to use a
minimum-version comparison instead of compareVersions(...) === 0, so 4.1.0 and
later keep the field enabled and existing startOnLoad values continue to be
preserved when saving tasks.
| const deleteMCPServer = (entry: any) => { | ||
| const inboundPath = entry.inboundEndpoint?.path; | ||
| const localEntryPath = entry.localEntry?.path; | ||
|
|
||
| const confirmed = window.confirm(`Are you sure you want to delete MCP Server "${entry.name}"? This action cannot be undone.`); | ||
| if (!confirmed) { | ||
| return; | ||
| } | ||
|
|
||
| if (inboundPath) { | ||
| rpcClient.getMiDiagramRpcClient().deleteArtifact({ path: inboundPath, enableUndo: false }); | ||
| } | ||
| if (localEntryPath) { | ||
| rpcClient.getMiDiagramRpcClient().deleteArtifact({ path: localEntryPath, enableUndo: false }); | ||
| } | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does window.confirm work inside a VS Code webview iframe?
💡 Result:
No, window.confirm does not work inside a VS Code webview [1][2][3]. VS Code intentionally blocks the use of window.confirm, window.alert, and window.prompt within webviews [2][3]. Because webviews operate within a sandboxed iframe environment, these browser-native modal dialogs are disabled by design to maintain a consistent UI experience and prevent untrusted or third-party content from disrupting the editor [2][3]. If your application requires user confirmation or input, the recommended approach is to use VS Code's native extension APIs, which are designed to handle these interactions within the editor's UI [1][2]: 1. Use postMessage: Send a message from your webview to your extension host using the acquireVsCodeApi instance [4]. 2. Invoke Native APIs: Inside your extension, receive the message and use VS Code's native UI methods, such as vscode.window.showInformationMessage or vscode.window.showQuickPick [1][2]. These methods support a modal option (e.g., {modal: true}) to provide a similar user experience to a standard confirmation dialog [1][2]. If you are using third-party libraries that rely on window.confirm or window.alert, you must override these global functions in your webview code to intercept the calls and redirect them to the extension host via postMessage [1][2].
Citations:
- 1: WebView optionally add "allow-modals" to iframe sandbox options microsoft/vscode#67109
- 2: https://stackoverflow.com/questions/56692461/workaround-to-allow-popups-in-vscode-webview-extension
- 3: window.alert, window.open not working in Notebook renderers microsoft/vscode-jupyter#12484
- 4: https://code.visualstudio.com/api/extension-guides/webview
Replace window.confirm with a VS Code modal. Native confirm dialogs are disabled in webviews, so this guard may not render; use an extension-host-backed showWarningMessage(..., { modal: true }) flow before calling deleteArtifact.
🤖 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/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx`
around lines 310 - 325, Replace the native confirmation in deleteMCPServer with
a VS Code modal confirmation flow, since window.confirm may not render in
webviews. Update deleteMCPServer to await an extension-host-backed
showWarningMessage call with { modal: true } before invoking
rpcClient.getMiDiagramRpcClient().deleteArtifact for inboundEndpoint.path and
localEntry.path, and keep the delete logic behind the modal result.
This PR syncs changes from stable/mi to the main branch.
Automated PR created by GitHub Actions.
Summary by CodeRabbit
New Features
bindsToon APIs/resources andstartOnLoadfor tasks.Bug Fixes
Chores