Skip to content

Commit 07590ea

Browse files
Merge branch 'presidio-oss:main' into document-update/readme
2 parents eaa54e3 + 3e02d30 commit 07590ea

28 files changed

Lines changed: 545 additions & 362 deletions

.changeset/lovely-avocados-do.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"hai-build-code-generator": minor
3+
---
4+
5+
Marking the Hai tasks as 'Completed' upon successful execution

.changeset/sharp-eels-accept.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"hai-build-code-generator": patch
3+
---
4+
5+
Fixed inline edit not working after cline latest merge (v3.8.6)

.vscodeignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ docs/**
4545
!node_modules/@vscode/codicons/dist/codicon.css
4646
!node_modules/@vscode/codicons/dist/codicon.ttf
4747

48+
#Include default experts folder
49+
!src/experts
50+
4851
# Include default themes JSON files used in getTheme
4952
!src/integrations/theme/default-themes/**
5053

src/core/controller/index.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,9 @@ export class Controller {
826826
case "loadExperts":
827827
await this.loadExperts()
828828
break
829+
case "loadDefaultExperts":
830+
await this.loadDefaultExperts()
831+
break
829832
case "refreshDocumentLink":
830833
if (message.text && message.expert) {
831834
await this.expertManager.refreshDocumentLink(this.vsCodeWorkSpaceFolderFsPath, message.expert, message.text)
@@ -962,6 +965,44 @@ export class Controller {
962965
break
963966
}
964967
break
968+
case "writeTaskStatus":
969+
// write status to the file
970+
const folder = message.folder
971+
const taskId = message?.taskId ?? ""
972+
const status = message?.status
973+
const taskIdMatch = taskId.match(/^(\d+)-US(\d+)-TASK(\d+)$/)
974+
if (!folder || !taskIdMatch || !status) {
975+
const message = `Failed to update task status. Error: Either folder, taskId or status is invalid.`
976+
vscode.window.showErrorMessage(message)
977+
} else {
978+
const [_, prdId, usId, taskId] = taskIdMatch
979+
const prdFeatureFilePath = path.join(`${folder}`, "PRD", `PRD${prdId}-feature.json`)
980+
try {
981+
const fileContent = await fs.readFile(prdFeatureFilePath, "utf-8")
982+
const prdFeatureJson = JSON.parse(fileContent)
983+
const feature = prdFeatureJson["features"].find((feature: { id: string }) => feature.id === `US${usId}`)
984+
if (feature) {
985+
const selectedTask = feature["tasks"].find((task: { id: string }) => task.id === `TASK${taskId}`)
986+
selectedTask.status = status
987+
}
988+
989+
await fs.writeFile(prdFeatureFilePath, JSON.stringify(prdFeatureJson, null, 2), "utf-8")
990+
const message = `Successfully marked task as ${status.toLowerCase()}.`
991+
vscode.window.showInformationMessage(message)
992+
await this.postMessageToWebview({
993+
type: "writeTaskStatus",
994+
writeTaskStatusResult: {
995+
success: true,
996+
message,
997+
status,
998+
},
999+
})
1000+
} catch (error) {
1001+
const message = `Failed to mark task as ${status.toLowerCase()}. Error: ${error.message}`
1002+
vscode.window.showErrorMessage(message)
1003+
}
1004+
}
1005+
break
9651006
default:
9661007
this.customWebViewMessageHandlers(message)
9671008
break
@@ -2457,7 +2498,13 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
24572498
.filter((file: string) => file.match(/\-feature.json$/))
24582499
.forEach((file: string) => {
24592500
const content = fs.readFileSync(path.join(`${url}/PRD`, file), "utf-8")
2460-
haiTaskList = [...haiTaskList, ...JSON.parse(content).features]
2501+
const prdId = file.split("-")[0].replace("PRD", "")
2502+
const parsedFeaturesList = JSON.parse(content).features
2503+
const featuresListWithPrdId = parsedFeaturesList.map((feature: any) => ({
2504+
...feature,
2505+
prdId: prdId,
2506+
}))
2507+
haiTaskList = [...haiTaskList, ...featuresListWithPrdId]
24612508
})
24622509
return haiTaskList
24632510
} catch (e) {
@@ -2570,6 +2617,14 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
25702617
})
25712618
}
25722619

2620+
async loadDefaultExperts() {
2621+
const experts = await this.expertManager.loadDefaultExperts()
2622+
await this.postMessageToWebview({
2623+
type: "defaultExpertsLoaded",
2624+
experts,
2625+
})
2626+
}
2627+
25732628
private async getExpertDocumentsContent(expertName: string): Promise<string> {
25742629
const expertPath = await this.expertManager.getExpertPromptPath(this.vsCodeWorkSpaceFolderFsPath, expertName)
25752630

src/core/experts/ExpertManager.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class ExpertManager {
1717

1818
public static readonly METADATA_FILE = "metadata.json"
1919
public static readonly PROMPT_FILE = "prompt.md"
20+
public static readonly ICON = "icon.svg"
2021
public static readonly DOCS_DIR = "docs"
2122
public static readonly STATUS_FILE = "status.json"
2223
public static readonly PLACEHOLDER_FILE = "placeholder.txt"
@@ -507,4 +508,60 @@ export class ExpertManager {
507508
}
508509
return content
509510
}
511+
512+
/**
513+
* Load the default Experts
514+
*/
515+
516+
async loadDefaultExperts(): Promise<ExpertData[]> {
517+
const expertsDir = path.join(this.extensionContext.extensionPath, GlobalFileNames.defaultExperts)
518+
519+
let experts: ExpertData[] = []
520+
521+
try {
522+
const directoryEntries = await fs.readdir(expertsDir, { withFileTypes: true })
523+
524+
for (const directoryEntry of directoryEntries) {
525+
if (!directoryEntry.isDirectory()) {
526+
continue
527+
}
528+
529+
const folderName = directoryEntry.name
530+
const folderPath = path.join(expertsDir, folderName)
531+
const promptPath = path.join(folderPath, ExpertManager.PROMPT_FILE)
532+
const iconPath = path.join(folderPath, ExpertManager.ICON)
533+
534+
let prompt = ""
535+
try {
536+
prompt = await fs.readFile(promptPath, "utf8")
537+
if (!prompt.trim()) {
538+
console.warn(`Empty prompt for ${folderName}, skipping...`)
539+
continue
540+
}
541+
} catch (error) {
542+
console.error(`Error reading prompt for ${folderName}:`, error)
543+
continue
544+
}
545+
546+
let iconBase64 = ""
547+
try {
548+
const svgContent = await fs.readFile(iconPath)
549+
iconBase64 = `data:image/svg+xml;base64,${svgContent.toString("base64")}`
550+
} catch {
551+
console.warn(`Icon not found for ${folderName}`)
552+
}
553+
554+
experts.push({
555+
name: folderName,
556+
prompt,
557+
isDefault: true,
558+
iconComponent: iconBase64,
559+
})
560+
}
561+
} catch (error) {
562+
console.error("Error reading experts directory:", error)
563+
}
564+
565+
return experts
566+
}
510567
}
File renamed without changes.

webview-ui/src/data/experts/dotnetExpert.ts renamed to src/experts/dotnet/prompt.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
export const DOTNET_EXPERT_PROMPT = `
21
## You are HAI , a specialized expert in .NET development with deep knowledge of the entire .NET ecosystem .
32

43
## .NET-Specific Rules
@@ -61,5 +60,4 @@ Ensure **separation of concerns** (Application, Domain, Infrastructure, API).
6160
### 10. Performance & Best Practices
6261
- Use **async/await** for non-blocking operations.
6362
- Implement caching (e.g., **MemoryCache, Redis**) for frequently accessed data.
64-
- Enforce **rate limiting** and **API throttling**.
65-
`
63+
- Enforce **rate limiting** and **API throttling**.
File renamed without changes.

webview-ui/src/data/experts/golangExpert.ts renamed to src/experts/golang/prompt.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
export const GOLANG_EXPERT_PROMPT = `
21
## You are HAI, a specialized expert in Go development with deep knowledge of idiomatic Go programming and the Go ecosystem.
32

43
## Go-Specific Rules
@@ -99,5 +98,4 @@ Ensure **package cohesion** (each package serves a single purpose).
9998
- Use **prepared statements** for database queries.
10099
- Apply **proper authentication** and authorization.
101100
- Handle **sensitive data** carefully; don't log credentials.
102-
- Run **security scanners** on your dependencies.
103-
`
101+
- Run **security scanners** on your dependencies.
File renamed without changes.

0 commit comments

Comments
 (0)