Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,34 +45,32 @@ inputs:
type: string
required: false
BALLERINA_AUTH_ORG:
default: true
type: string
BALLERINA_AUTH_CLIENT_ID:
default: true
type: string
BALLERINA_DEV_COPLIOT_ROOT_URL:
type: string
BALLERINA_DEV_COPLIOT_AUTH_ORG:
type: string
BALLERINA_DEV_COPLIOT_AUTH_CLIENT_ID:
type: string
BALLERINA_DEV_COPLIOT_AUTH_REDIRECT_URL:
type: string
MI_AUTH_ORG:
default: true
type: string
MI_AUTH_CLIENT_ID:
default: true
type: string
PLATFORM_DEFAULT_GHAPP_CLIENT_ID:
default: true
type: string
PLATFORM_DEFAULT_DEVANT_ASGARDEO_CLIENT_ID:
default: true
type: string
PLATFORM_STAGE_GHAPP_CLIENT_ID:
default: true
type: string
PLATFORM_STAGE_DEVANT_ASGARDEO_CLIENT_ID:
default: true
type: string
PLATFORM_DEV_GHAPP_CLIENT_ID:
default: true
type: string
PLATFORM_DEV_DEVANT_ASGARDEO_CLIENT_ID:
default: true
type: string

runs:
Expand Down Expand Up @@ -167,6 +165,10 @@ runs:
isPreRelease: ${{ inputs.isPreRelease == 'true' }}
BALLERINA_AUTH_ORG: ${{ inputs.BALLERINA_AUTH_ORG }}
BALLERINA_AUTH_CLIENT_ID: ${{ inputs.BALLERINA_AUTH_CLIENT_ID }}
BALLERINA_DEV_COPLIOT_ROOT_URL: ${{ inputs.BALLERINA_DEV_COPLIOT_ROOT_URL }}
BALLERINA_DEV_COPLIOT_AUTH_ORG: ${{ inputs.BALLERINA_DEV_COPLIOT_AUTH_ORG }}
BALLERINA_DEV_COPLIOT_AUTH_CLIENT_ID: ${{ inputs.BALLERINA_DEV_COPLIOT_AUTH_CLIENT_ID }}
BALLERINA_DEV_COPLIOT_AUTH_REDIRECT_URL: ${{ inputs.BALLERINA_DEV_COPLIOT_AUTH_REDIRECT_URL }}
MI_AUTH_ORG: ${{ inputs.MI_AUTH_ORG }}
MI_AUTH_CLIENT_ID: ${{ inputs.MI_AUTH_CLIENT_ID }}
PLATFORM_DEFAULT_GHAPP_CLIENT_ID: ${{ inputs.PLATFORM_DEFAULT_GHAPP_CLIENT_ID }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ jobs:
token: ${{ secrets.CHOREO_BOT_TOKEN }}
BALLERINA_AUTH_ORG: ${{ secrets.BALLERINA_AUTH_ORG }}
BALLERINA_AUTH_CLIENT_ID: ${{ secrets.BALLERINA_AUTH_CLIENT_ID }}
BALLERINA_DEV_COPLIOT_ROOT_URL: ${{ secrets.BALLERINA_DEV_COPLIOT_ROOT_URL }}
BALLERINA_DEV_COPLIOT_AUTH_ORG: ${{ secrets.BALLERINA_DEV_COPLIOT_AUTH_ORG }}
BALLERINA_DEV_COPLIOT_AUTH_CLIENT_ID: ${{ secrets.BALLERINA_DEV_COPLIOT_AUTH_CLIENT_ID }}
BALLERINA_DEV_COPLIOT_AUTH_REDIRECT_URL: ${{ secrets.BALLERINA_DEV_COPLIOT_AUTH_REDIRECT_URL }}
MI_AUTH_ORG: ${{ secrets.MI_AUTH_ORG }}
MI_AUTH_CLIENT_ID: ${{ secrets.MI_AUTH_CLIENT_ID }}
PLATFORM_DEFAULT_GHAPP_CLIENT_ID: ${{ secrets.PLATFORM_DEFAULT_GHAPP_CLIENT_ID }}
Expand Down
2 changes: 0 additions & 2 deletions workspaces/ballerina/ballerina-extension/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,3 @@ BALLERINA_DEV_COPLIOT_ROOT_URL=
BALLERINA_DEV_COPLIOT_AUTH_ORG=
BALLERINA_DEV_COPLIOT_AUTH_CLIENT_ID=
BALLERINA_DEV_COPLIOT_AUTH_REDIRECT_URL=
BALLERINA_DEV_COPLIOT_CODE_API_KEY=
BALLERINA_DEV_COPLIOT_ASK_API_KEY=
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function determineAffectedPackages(
console.log(`[determineAffectedPackages] Temp project path: ${tempProjectPath}`);

// For non-workspace scenario (single package)
if (!ctx.workspacePath || projects.length === 1) {
if (!ctx.workspacePath) {
console.log(`[determineAffectedPackages] Non-workspace scenario, using temp project path: ${tempProjectPath}`);
affectedPackages.add(tempProjectPath);
return Array.from(affectedPackages);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
// specific language governing permissions and limitations
// under the License.

import { SourceFile, FileChanges, CodeContext, ProjectSource, ExecutionContext } from "@wso2/ballerina-core";
import { SourceFile, FileChanges, CodeContext, ProjectSource, ExecutionContext, PROJECT_KIND } from "@wso2/ballerina-core";
import { addToIntegration } from "../../../rpc-managers/ai-panel/utils";
import * as fs from "fs";
import * as path from "path";
import type { TextEdit } from "vscode-languageserver-protocol";
import { StateMachine } from "../../../stateMachine";

/**
* File extensions to include in codebase structure
Expand Down Expand Up @@ -215,34 +216,22 @@ export function formatCodebaseStructure(projects: ProjectSource[]): string {
text += "You do not need to acknowledge or list these files in your response. ";
text += "This information is provided for your awareness only.\n\n";

if (projects.length === 1) {
// Single project case: show project name and files with content
const project = projects[0];
const files = collectFilesFromProject(project);
const context = StateMachine.context();
const isWorkspace = context.projectInfo?.projectKind === PROJECT_KIND.WORKSPACE_PROJECT;
for (const project of projects) {
const files = collectFilesFromProject(project, isWorkspace);
const activeStatus = project.isActive ? ' active="true"' : "";

text += `<project name="${project.projectName}">\n`;
text += `<project name="${project.projectName}"${activeStatus}>\n`;
text += "<files>\n";
text += files.map(formatFileWithContent).join("\n");
text += "\n</files>\n";
text += "</project>\n";
} else {
// Multi-workspace project case: show all projects with active status
// Include packagePath prefix in file paths for clarity
for (const project of projects) {
const files = collectFilesFromProject(project, true);
const activeStatus = project.isActive ? ' active="true"' : "";

text += `<project name="${project.projectName}"${activeStatus}>\n`;
text += "<files>\n";
text += files.map(formatFileWithContent).join("\n");
text += "\n</files>\n";
text += "</project>\n";
}
}

text += "</codebase_structure>";

if (projects.length > 0) {
if (isWorkspace) {
text += `Note: This is a Ballerina workspace with multiple packages. File paths are prefixed with their package paths (e.g., "mainpackage/main.bal").
Files from external packages (not the active package) are marked with the externalPackageName attribute (e.g., <file filename="otherpackage/main.bal" externalPackageName="otherpackage">).
You can import these packages by just using the package name (e.g., import otherpackage;).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,14 +295,11 @@ export class VisualizerRpcManager implements VisualizerAPI {
reviewAccepted(): void {
// When user accepts changes in review mode, navigate back to normal view
console.log("Review accepted - changes will be kept");
// Navigate to package overview or appropriate view
const isWithinBallerinaWorkspace = !!StateMachine.context().workspacePath;
// Navigate to package overview
openView(
EVENT_TYPE.OPEN_VIEW,
{
view: isWithinBallerinaWorkspace
? MACHINE_VIEW.WorkspaceOverview
: MACHINE_VIEW.PackageOverview
view: MACHINE_VIEW.PackageOverview
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function convertToReviewView(diff: SemanticDiff, projectPath: string, packageNam
const fileName = diff.uri.split("/").pop() || diff.uri;
const changeTypeStr = getChangeTypeString(diff.changeType);
const nodeKindStr = getNodeKindString(diff.nodeKind);

// Include package name in label if provided (for multi-package scenarios)
const changeLabel = packageName
? `${changeTypeStr}: ${nodeKindStr} in ${packageName}/${fileName}`
Expand Down Expand Up @@ -209,7 +209,7 @@ async function fetchSemanticDiff(rpcClient: any, projectPath: string): Promise<S
// Utility function to fetch semantic diffs for multiple packages
async function fetchSemanticDiffForMultiplePackages(
rpcClient: any,
packagePaths: string[]
packagePaths: string[],
): Promise<SemanticDiffResponse> {
console.log(`[ReviewMode] Fetching semantic diffs for ${packagePaths.length} packages:`, packagePaths);

Expand Down Expand Up @@ -241,12 +241,12 @@ async function fetchSemanticDiffForMultiplePackages(
function getPackageName(path: string): string {
const parts = path.split("/");
const lastPart = parts[parts.length - 1];

// If the last part is a .bal file, the package name is the directory before it
if (lastPart && lastPart.endsWith('.bal')) {
if (lastPart && lastPart.endsWith(".bal")) {
return parts[parts.length - 2] || path;
}

// Otherwise, the last part is the package name
return lastPart || path;
}
Expand Down Expand Up @@ -276,7 +276,7 @@ export function ReviewMode(): JSX.Element {
const loadSemanticDiff = useCallback(async () => {
try {
setIsLoading(true);

// First fetch the active temp directory path
const tempDirPath = await rpcClient.getAiPanelRpcClient().getActiveTempDir();
if (!tempDirPath) {
Expand Down Expand Up @@ -308,7 +308,10 @@ export function ReviewMode(): JSX.Element {
// Use affected packages if available, otherwise fallback to temp directory
const packagesToReview = isWorkspaceProject ? fetchedPackages : [tempDirPath];

console.log(`[ReviewMode] Reviewing ${packagesToReview.length} package(s) in ${isWorkspaceProject ? 'workspace' : 'single'} project:`, packagesToReview);
console.log(
`[ReviewMode] Reviewing ${packagesToReview.length} package(s) in ${isWorkspaceProject ? "workspace" : "single"} project:`,
packagesToReview,
);

// Fetch semantic diffs for all affected packages
// For workspace projects, always fetch for each package even if only one is affected
Expand All @@ -326,13 +329,10 @@ export function ReviewMode(): JSX.Element {
if (semanticDiffResponse.loadDesignDiagrams && semanticDiffResponse.semanticDiffs.length > 0) {
// For workspace projects, create a component diagram for each affected package
// For single package projects, create one component diagram

packagesToReview.forEach((packagePath) => {
const packageName = getPackageName(packagePath);
const label = isWorkspaceProject
? `Design Diagram - ${packageName}`
: "Design Diagram";

const label = isWorkspaceProject ? `Design Diagram - ${packageName}` : "Design Diagram";

allViews.push({
type: DiagramType.COMPONENT,
filePath: packagePath,
Expand Down Expand Up @@ -362,9 +362,9 @@ export function ReviewMode(): JSX.Element {
// Find the package that contains this file
for (const pkgPath of packagesToReview) {
// Normalize paths and check if diff.uri starts with package path
const normalizedUri = diff.uri.replace(/\\/g, '/');
const normalizedPkgPath = pkgPath.replace(/\\/g, '/');
if (normalizedUri.startsWith(normalizedPkgPath + '/') || normalizedUri === normalizedPkgPath) {
const normalizedUri = diff.uri.replace(/\\/g, "/");
const normalizedPkgPath = pkgPath.replace(/\\/g, "/");
if (normalizedUri.startsWith(normalizedPkgPath + "/") || normalizedUri === normalizedPkgPath) {
belongsToPackage = pkgPath;
packageName = getPackageName(pkgPath);
break;
Expand Down Expand Up @@ -541,7 +541,14 @@ export function ReviewMode(): JSX.Element {
<ReviewContainer>
<TitleBar
title="No Changes"
actions={<ReviewModeBadge>Review Mode</ReviewModeBadge>}
actions={
<>
<ReviewModeBadge>Review Mode</ReviewModeBadge>
<CloseButton onClick={handleClose} title="Close Review Mode">
<Icon name="bi-close" />
</CloseButton>
</>
}
hideBack={true}
hideUndoRedo={true}
/>
Expand Down Expand Up @@ -598,7 +605,7 @@ export function ReviewMode(): JSX.Element {
<>
{isWorkspace && currentPackageName && (
<CurrentPackageBadge title={`Currently viewing: ${currentPackageName} Integration`}>
<Codicon name="project"/>
<Codicon name="project" />
{currentPackageName}
</CurrentPackageBadge>
)}
Expand Down
Loading