diff --git a/.schemas/collection.schema.json b/.schemas/collection.schema.json
index e4efe3a..0119882 100644
--- a/.schemas/collection.schema.json
+++ b/.schemas/collection.schema.json
@@ -57,6 +57,10 @@
"type": "string",
"description": "Type of the item",
"enum": ["prompt", "instruction", "chat-mode"]
+ },
+ "usage": {
+ "type": "string",
+ "description": "Optional usage context for the item"
}
}
},
@@ -81,4 +85,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/README.collections.md b/README.collections.md
index b5db549..4b2df4e 100644
--- a/README.collections.md
+++ b/README.collections.md
@@ -25,5 +25,6 @@ Curated collections of related prompts, instructions, and chat modes organized a
| [Power Apps Code Apps Development](collections/power-apps-code-apps.md) | Complete toolkit for Power Apps Code Apps development including project scaffolding, development standards, and expert guidance for building code-first applications with Power Platform integration. | 3 items | power-apps, power-platform, typescript, react, code-apps, dataverse, connectors |
| [Project Planning & Management](collections/project-planning.md) | Tools and guidance for software project planning, feature breakdown, epic management, implementation planning, and task organization for development teams. | 17 items | planning, project-management, epic, feature, implementation, task, architecture, technical-spike |
| [Security & Code Quality](collections/security-best-practices.md) | Security frameworks, accessibility guidelines, performance optimization, and code quality best practices for building secure, maintainable, and high-performance applications. | 6 items | security, accessibility, performance, code-quality, owasp, a11y, optimization, best-practices |
+| [Tasks by microsoft/edge-ai](collections/edge-ai-tasks.md) | Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai | 3 items | architecture, planning, research, tasks, implementation |
| [Technical Spike](collections/technical-spike.md) | Tools for creation, management and research of technical spikes to reduce unknowns and assumptions before proceeding to specification and implementation of solutions. | 2 items | technical-spike, assumption-testing, validation, research |
| [Testing & Test Automation](collections/testing-automation.md) | Comprehensive collection for writing tests, test automation, and test-driven development including unit tests, integration tests, and end-to-end testing strategies. | 11 items | testing, tdd, automation, unit-tests, integration, playwright, jest, nunit |
diff --git a/collections/edge-ai-tasks.collection.yml b/collections/edge-ai-tasks.collection.yml
new file mode 100644
index 0000000..316e2de
--- /dev/null
+++ b/collections/edge-ai-tasks.collection.yml
@@ -0,0 +1,90 @@
+id: edge-ai-tasks
+name: Tasks by microsoft/edge-ai
+description: Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai
+tags: [architecture, planning, research, tasks, implementation]
+items:
+ # Planning Chat Modes
+ - path: chatmodes/task-researcher.chatmode.md
+ kind: chat-mode
+ usage: |
+ Now you can iterate on research for your tasks!
+
+ ```markdown, research.prompt.md
+ ---
+ mode: task-researcher
+ title: Research microsoft fabric realtime intelligence terraform support
+ ---
+ Review the microsoft documentation for fabric realtime intelligence
+ and come up with ideas on how to implement this support into our terraform components.
+ ```
+
+ Research is dumped out into a .copilot-tracking/research/*-research.md file and will include discoveries for GHCP along with examples and schema that will be useful during implementation.
+
+ Also, task-researcher will provide additional ideas for implementation which you can work with GitHub Copilot on selecting the right one to focus on.
+
+ - path: chatmodes/task-planner.chatmode.md
+ kind: chat-mode
+ usage: |
+ Also, task-researcher will provide additional ideas for implementation which you can work with GitHub Copilot on selecting the right one to focus on.
+
+ ```markdown, task-plan.prompt.md
+ ---
+ mode: task-planner
+ title: Plan microsoft fabric realtime intelligence terraform support
+ ---
+ #file: .copilot-tracking/research/*-fabric-rti-blueprint-modification-research.md
+ Build a plan to support adding fabric rti to this project
+ ```
+
+ `task-planner` will help you create a plan for implementing your task(s). It will use your fully researched ideas or build new research if not already provided.
+
+ `task-planner` will produce three (3) files that will be used by `task-implementation.instructions.md`.
+
+ * `.copilot-tracking/plan/*-plan.instructions.md`
+
+ * A newly generated instructions file that has the plan as a checklist of Phases and Tasks.
+ * `.copilot-tracking/details/*-details.md`
+
+ * The details for the implementation, the plan file refers to this file for specific details (important if you have a big plan).
+ * `.copilot-tracking/prompts/implement-*.prompt.md`
+
+ * A newly generated prompt file that will create a `.copilot-tracking/changes/*-changes.md` file and proceed to implement the changes.
+
+ Continue to use `task-planner` to iterate on the plan until you have exactly what you want done to your codebase.
+
+ # Planning Instructions
+ - path: instructions/task-implementation.instructions.md
+ kind: instruction
+ usage: |
+ Continue to use `task-planner` to iterate on the plan until you have exactly what you want done to your codebase.
+
+ When you are ready to implement the plan, **create a new chat** and switch to `Agent` mode then fire off the newly generated prompt.
+
+ ```markdown, implement-fabric-rti-changes.prompt.md
+ ---
+ mode: agent
+ title: Implement microsoft fabric realtime intelligence terraform support
+ ---
+ /implement-fabric-rti-blueprint-modification phaseStop=true
+ ```
+
+ This prompt has the added benefit of attaching the plan as instructions, which helps with keeping the plan in context throughout the whole conversation.
+
+ **Expert Warning** ->>Use `phaseStop=false` to have Copilot implement the whole plan without stopping. Additionally, you can use `taskStop=true` to have Copilot stop after every Task implementation for finer detail control.
+
+ To use these generated instructions and prompts, you'll need to update your `settings.json` accordingly:
+
+ ```json
+ "chat.instructionsFilesLocations": {
+ // Existing instructions folders...
+ ".copilot-tracking/plans": true
+ },
+ "chat.promptFilesLocations": {
+ // Existing prompts folders...
+ ".copilot-tracking/prompts": true
+ },
+ ```
+
+display:
+ ordering: alpha # or "manual" to preserve the order above
+ show_badge: false # set to true to show collection badge on items
diff --git a/collections/edge-ai-tasks.md b/collections/edge-ai-tasks.md
new file mode 100644
index 0000000..75559ca
--- /dev/null
+++ b/collections/edge-ai-tasks.md
@@ -0,0 +1,100 @@
+# Tasks by microsoft/edge-ai
+
+Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai
+
+**Tags:** architecture, planning, research, tasks, implementation
+
+## Items in this Collection
+
+| Title | Type | Description |
+| ----- | ---- | ----------- |
+| [Task Researcher Instructions](../chatmodes/task-researcher.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-researcher.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-researcher.chatmode.md) | Chat Mode | Task research specialist for comprehensive project analysis - Brought to you by microsoft/edge-ai [see usage](#task-researcher-instructions) |
+| [Task Planner Instructions](../chatmodes/task-planner.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-planner.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-planner.chatmode.md) | Chat Mode | Task planner for creating actionable implementation plans - Brought to you by microsoft/edge-ai [see usage](#task-planner-instructions) |
+| [Task Plan Implementation Instructions](../instructions/task-implementation.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftask-implementation.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftask-implementation.instructions.md) | Instruction | Instructions for implementing task plans with progressive tracking and change record - Brought to you by microsoft/edge-ai [see usage](#task-plan-implementation-instructions) |
+
+## Collection Usage
+
+### Task Researcher Instructions
+
+Now you can iterate on research for your tasks!
+
+```markdown, research.prompt.md
+---
+mode: task-researcher
+title: Research microsoft fabric realtime intelligence terraform support
+---
+Review the microsoft documentation for fabric realtime intelligence
+and come up with ideas on how to implement this support into our terraform components.
+```
+
+Research is dumped out into a .copilot-tracking/research/*-research.md file and will include discoveries for GHCP along with examples and schema that will be useful during implementation.
+
+Also, task-researcher will provide additional ideas for implementation which you can work with GitHub Copilot on selecting the right one to focus on.
+
+---
+
+### Task Planner Instructions
+
+Also, task-researcher will provide additional ideas for implementation which you can work with GitHub Copilot on selecting the right one to focus on.
+
+```markdown, task-plan.prompt.md
+---
+mode: task-planner
+title: Plan microsoft fabric realtime intelligence terraform support
+---
+#file: .copilot-tracking/research/*-fabric-rti-blueprint-modification-research.md
+Build a plan to support adding fabric rti to this project
+```
+
+`task-planner` will help you create a plan for implementing your task(s). It will use your fully researched ideas or build new research if not already provided.
+
+`task-planner` will produce three (3) files that will be used by `task-implementation.instructions.md`.
+
+* `.copilot-tracking/plan/*-plan.instructions.md`
+
+ * A newly generated instructions file that has the plan as a checklist of Phases and Tasks.
+* `.copilot-tracking/details/*-details.md`
+
+ * The details for the implementation, the plan file refers to this file for specific details (important if you have a big plan).
+* `.copilot-tracking/prompts/implement-*.prompt.md`
+
+ * A newly generated prompt file that will create a `.copilot-tracking/changes/*-changes.md` file and proceed to implement the changes.
+
+Continue to use `task-planner` to iterate on the plan until you have exactly what you want done to your codebase.
+
+---
+
+### Task Plan Implementation Instructions
+
+Continue to use `task-planner` to iterate on the plan until you have exactly what you want done to your codebase.
+
+When you are ready to implement the plan, **create a new chat** and switch to `Agent` mode then fire off the newly generated prompt.
+
+```markdown, implement-fabric-rti-changes.prompt.md
+---
+mode: agent
+title: Implement microsoft fabric realtime intelligence terraform support
+---
+/implement-fabric-rti-blueprint-modification phaseStop=true
+```
+
+This prompt has the added benefit of attaching the plan as instructions, which helps with keeping the plan in context throughout the whole conversation.
+
+**Expert Warning** ->>Use `phaseStop=false` to have Copilot implement the whole plan without stopping. Additionally, you can use `taskStop=true` to have Copilot stop after every Task implementation for finer detail control.
+
+To use these generated instructions and prompts, you'll need to update your `settings.json` accordingly:
+
+```json
+ "chat.instructionsFilesLocations": {
+ // Existing instructions folders...
+ ".copilot-tracking/plans": true
+ },
+ "chat.promptFilesLocations": {
+ // Existing prompts folders...
+ ".copilot-tracking/prompts": true
+ },
+```
+
+---
+
+*This collection includes 3 curated items for tasks by microsoft/edge-ai.*
\ No newline at end of file
diff --git a/update-readme.js b/update-readme.js
index 2c71dba..d6ce2da 100755
--- a/update-readme.js
+++ b/update-readme.js
@@ -142,7 +142,10 @@ function extractTitle(filePath) {
// Track code blocks to ignore headings inside them
if (frontmatterEnded2) {
- if (line.trim().startsWith("```") || line.trim().startsWith("````")) {
+ if (
+ line.trim().startsWith("```") ||
+ line.trim().startsWith("````")
+ ) {
inCodeBlock = !inCodeBlock;
continue;
}
@@ -156,7 +159,10 @@ function extractTitle(filePath) {
// No frontmatter, look for first heading (but not in code blocks)
let inCodeBlock = false;
for (const line of lines) {
- if (line.trim().startsWith("```") || line.trim().startsWith("````")) {
+ if (
+ line.trim().startsWith("```") ||
+ line.trim().startsWith("````")
+ ) {
inCodeBlock = !inCodeBlock;
continue;
}
@@ -260,7 +266,9 @@ function extractDescription(filePath) {
let description = descriptionMatch[1];
// Check if the description is wrapped in single quotes and handle escaped quotes
- const singleQuoteMatch = line.match(/^description:\s*'(.+?)'\s*$/);
+ const singleQuoteMatch = line.match(
+ /^description:\s*'(.+?)'\s*$/
+ );
if (singleQuoteMatch) {
// Replace escaped single quotes ('') with single quotes (')
description = singleQuoteMatch[1].replace(/''/g, "'");
@@ -308,8 +316,12 @@ const AKA_INSTALL_URLS = {
function makeBadges(link, type) {
const aka = AKA_INSTALL_URLS[type] || AKA_INSTALL_URLS.instructions;
- const vscodeUrl = `${aka}?url=${encodeURIComponent(`vscode:chat-${type}/install?url=${repoBaseUrl}/${link}`)}`;
- const insidersUrl = `${aka}?url=${encodeURIComponent(`vscode-insiders:chat-${type}/install?url=${repoBaseUrl}/${link}`)}`;
+ const vscodeUrl = `${aka}?url=${encodeURIComponent(
+ `vscode:chat-${type}/install?url=${repoBaseUrl}/${link}`
+ )}`;
+ const insidersUrl = `${aka}?url=${encodeURIComponent(
+ `vscode-insiders:chat-${type}/install?url=${repoBaseUrl}/${link}`
+ )}`;
return `[](${vscodeUrl})
[](${insidersUrl})`;
}
@@ -405,8 +417,7 @@ function generatePromptsSection(promptsDir) {
}
// Create table header
- let promptsContent =
- "| Title | Description |\n| ----- | ----------- |\n";
+ let promptsContent = "| Title | Description |\n| ----- | ----------- |\n";
// Generate table rows for each prompt file
for (const entry of promptEntries) {
@@ -462,8 +473,7 @@ function generateChatModesSection(chatmodesDir) {
}
// Create table header
- let chatmodesContent =
- "| Title | Description |\n| ----- | ----------- |\n";
+ let chatmodesContent = "| Title | Description |\n| ----- | ----------- |\n";
// Generate table rows for each chat mode file
for (const entry of chatmodeEntries) {
@@ -502,19 +512,22 @@ function generateCollectionsSection(collectionsDir) {
.filter((file) => file.endsWith(".collection.yml"));
// Map collection files to objects with name for sorting
- const collectionEntries = collectionFiles.map((file) => {
- const filePath = path.join(collectionsDir, file);
- const collection = parseCollectionYaml(filePath);
+ const collectionEntries = collectionFiles
+ .map((file) => {
+ const filePath = path.join(collectionsDir, file);
+ const collection = parseCollectionYaml(filePath);
- if (!collection) {
- console.warn(`Failed to parse collection: ${file}`);
- return null;
- }
+ if (!collection) {
+ console.warn(`Failed to parse collection: ${file}`);
+ return null;
+ }
- const collectionId = collection.id || path.basename(file, ".collection.yml");
- const name = collection.name || collectionId;
- return { file, filePath, collection, collectionId, name };
- }).filter(entry => entry !== null); // Remove failed parses
+ const collectionId =
+ collection.id || path.basename(file, ".collection.yml");
+ const name = collection.name || collectionId;
+ return { file, filePath, collection, collectionId, name };
+ })
+ .filter((entry) => entry !== null); // Remove failed parses
// Sort by name alphabetically
collectionEntries.sort((a, b) => a.name.localeCompare(b.name));
@@ -566,6 +579,9 @@ function generateCollectionReadme(collection, collectionId) {
content += `## Items in this Collection\n\n`;
content += `| Title | Type | Description |\n| ----- | ---- | ----------- |\n`;
+ let collectionUsageHeader = "## Collection Usage\n\n";
+ let collectionUsageContent = [];
+
// Sort items based on display.ordering setting
const items = [...collection.items];
if (collection.display?.ordering === "alpha") {
@@ -580,19 +596,52 @@ function generateCollectionReadme(collection, collectionId) {
const filePath = path.join(__dirname, item.path);
const title = extractTitle(filePath);
const description = extractDescription(filePath) || "No description";
- const typeDisplay = item.kind === "chat-mode" ? "Chat Mode" :
- item.kind === "instruction" ? "Instruction" : "Prompt";
+
+ const typeDisplay =
+ item.kind === "chat-mode"
+ ? "Chat Mode"
+ : item.kind === "instruction"
+ ? "Instruction"
+ : "Prompt";
const link = `../${item.path}`;
// Create install badges for each item
- const badges = makeBadges(item.path, item.kind === "instruction" ? "instructions" :
- item.kind === "chat-mode" ? "mode" : "prompt");
+ const badges = makeBadges(
+ item.path,
+ item.kind === "instruction"
+ ? "instructions"
+ : item.kind === "chat-mode"
+ ? "mode"
+ : "prompt"
+ );
- content += `| [${title}](${link})
${badges} | ${typeDisplay} | ${description} |\n`;
+ const usageDescription = item.usage
+ ? `${description} [see usage](#${title
+ .replace(/\s+/g, "-")
+ .toLowerCase()})`
+ : description;
+
+ content += `| [${title}](${link})
${badges} | ${typeDisplay} | ${usageDescription} |\n`;
+ // Generate Usage section for each collection
+ if (item.usage && item.usage.trim()) {
+ collectionUsageContent.push(
+ `### ${title}\n\n${item.usage.trim()}\n\n---\n\n`
+ );
+ }
}
+ // Append the usage section if any items had usage defined
+ if (collectionUsageContent.length > 0) {
+ content += `\n${collectionUsageHeader}${collectionUsageContent.join("")}`;
+ } else if (collection.display?.show_badge) {
+ content += "\n---\n";
+ }
+
+ // Optional badge note at the end if show_badge is true
if (collection.display?.show_badge) {
- content += `\n---\n*This collection includes ${items.length} curated items for ${name.toLowerCase()}.*`;
+ content += `*This collection includes ${
+ items.length
+ } curated items for ${name.toLowerCase()}.*`;
}
return content;
@@ -604,12 +653,16 @@ function writeFileIfChanged(filePath, content) {
if (exists) {
const original = fs.readFileSync(filePath, "utf8");
if (original === content) {
- console.log(`${path.basename(filePath)} is already up to date. No changes needed.`);
+ console.log(
+ `${path.basename(filePath)} is already up to date. No changes needed.`
+ );
return;
}
}
fs.writeFileSync(filePath, content);
- console.log(`${path.basename(filePath)} ${exists ? "updated" : "created"} successfully!`);
+ console.log(
+ `${path.basename(filePath)} ${exists ? "updated" : "created"} successfully!`
+ );
}
// Build per-category README content using existing generators, upgrading headings to H1
@@ -633,10 +686,16 @@ try {
const collectionsDir = path.join(__dirname, "collections");
// Compose headers for standalone files by converting section headers to H1
- const instructionsHeader = TEMPLATES.instructionsSection.replace(/^##\s/m, "# ");
+ const instructionsHeader = TEMPLATES.instructionsSection.replace(
+ /^##\s/m,
+ "# "
+ );
const promptsHeader = TEMPLATES.promptsSection.replace(/^##\s/m, "# ");
const chatmodesHeader = TEMPLATES.chatmodesSection.replace(/^##\s/m, "# ");
- const collectionsHeader = TEMPLATES.collectionsSection.replace(/^##\s/m, "# ");
+ const collectionsHeader = TEMPLATES.collectionsSection.replace(
+ /^##\s/m,
+ "# "
+ );
const instructionsReadme = buildCategoryReadme(
generateInstructionsSection,
@@ -666,10 +725,19 @@ try {
);
// Write category outputs
- writeFileIfChanged(path.join(__dirname, "README.instructions.md"), instructionsReadme);
+ writeFileIfChanged(
+ path.join(__dirname, "README.instructions.md"),
+ instructionsReadme
+ );
writeFileIfChanged(path.join(__dirname, "README.prompts.md"), promptsReadme);
- writeFileIfChanged(path.join(__dirname, "README.chatmodes.md"), chatmodesReadme);
- writeFileIfChanged(path.join(__dirname, "README.collections.md"), collectionsReadme);
+ writeFileIfChanged(
+ path.join(__dirname, "README.chatmodes.md"),
+ chatmodesReadme
+ );
+ writeFileIfChanged(
+ path.join(__dirname, "README.collections.md"),
+ collectionsReadme
+ );
// Generate individual collection README files
if (fs.existsSync(collectionsDir)) {
@@ -684,8 +752,12 @@ try {
const collection = parseCollectionYaml(filePath);
if (collection) {
- const collectionId = collection.id || path.basename(file, ".collection.yml");
- const readmeContent = generateCollectionReadme(collection, collectionId);
+ const collectionId =
+ collection.id || path.basename(file, ".collection.yml");
+ const readmeContent = generateCollectionReadme(
+ collection,
+ collectionId
+ );
const readmeFile = path.join(collectionsDir, `${collectionId}.md`);
writeFileIfChanged(readmeFile, readmeContent);
}
diff --git a/yaml-parser.js b/yaml-parser.js
index b209908..40ede78 100644
--- a/yaml-parser.js
+++ b/yaml-parser.js
@@ -20,14 +20,53 @@ function parseCollectionYaml(filePath) {
let currentArray = null;
let currentObject = null;
+ const readLiteralBlock = (startIndex, parentIndent) => {
+ const blockLines = [];
+ let blockIndent = null;
+ let index = startIndex;
+
+ for (; index < lines.length; index++) {
+ const rawLine = lines[index];
+ const trimmedLine = rawLine.trimEnd();
+ const contentOnly = trimmedLine.trim();
+ const lineIndent = rawLine.length - rawLine.trimLeft().length;
+
+ if (contentOnly === "" && blockIndent === null) {
+ // Preserve leading blank lines inside the literal block
+ blockLines.push("");
+ continue;
+ }
+
+ if (contentOnly !== "" && lineIndent <= parentIndent) {
+ break;
+ }
+
+ if (contentOnly === "") {
+ blockLines.push("");
+ continue;
+ }
+
+ if (blockIndent === null) {
+ blockIndent = lineIndent;
+ }
+
+ blockLines.push(rawLine.slice(blockIndent));
+ }
+
+ return {
+ content: blockLines.join("\n").replace(/\r/g, "").trimEnd(),
+ nextIndex: index - 1,
+ };
+ };
+
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const trimmed = line.trim();
-
+
if (!trimmed || trimmed.startsWith("#")) continue;
const leadingSpaces = line.length - line.trimLeft().length;
-
+
// Handle array items starting with -
if (trimmed.startsWith("- ")) {
if (currentKey === "items") {
@@ -35,12 +74,12 @@ function parseCollectionYaml(filePath) {
currentArray = [];
result[currentKey] = currentArray;
}
-
+
// Parse item object
const item = {};
currentArray.push(item);
currentObject = item;
-
+
// Handle inline properties on same line as -
const restOfLine = trimmed.substring(2).trim();
if (restOfLine) {
@@ -65,13 +104,13 @@ function parseCollectionYaml(filePath) {
const colonIndex = trimmed.indexOf(":");
const key = trimmed.substring(0, colonIndex).trim();
let value = trimmed.substring(colonIndex + 1).trim();
-
+
if (leadingSpaces === 0) {
// Top-level property
currentKey = key;
currentArray = null;
currentObject = null;
-
+
if (value) {
// Handle array format [item1, item2, item3]
if (value.startsWith("[") && value.endsWith("]")) {
@@ -82,6 +121,10 @@ function parseCollectionYaml(filePath) {
result[key] = [];
}
currentKey = null; // Reset since we handled the array
+ } else if (value === "|" || value === ">") {
+ const { content: blockContent, nextIndex } = readLiteralBlock(i + 1, leadingSpaces);
+ result[key] = blockContent;
+ i = nextIndex;
} else {
result[key] = value;
}
@@ -95,14 +138,26 @@ function parseCollectionYaml(filePath) {
}
} else if (currentObject && leadingSpaces > 0) {
// Property of current object (e.g., display properties)
- currentObject[key] = value === "true" ? true : value === "false" ? false : value;
+ if (value === "|" || value === ">") {
+ const { content: blockContent, nextIndex } = readLiteralBlock(i + 1, leadingSpaces);
+ currentObject[key] = blockContent;
+ i = nextIndex;
+ } else {
+ currentObject[key] = value === "true" ? true : value === "false" ? false : value;
+ }
} else if (currentArray && currentObject && leadingSpaces > 2) {
// Property of array item object
- currentObject[key] = value;
+ if (value === "|" || value === ">") {
+ const { content: blockContent, nextIndex } = readLiteralBlock(i + 1, leadingSpaces);
+ currentObject[key] = blockContent;
+ i = nextIndex;
+ } else {
+ currentObject[key] = value;
+ }
}
}
}
-
+
return result;
},
filePath,
@@ -110,4 +165,4 @@ function parseCollectionYaml(filePath) {
);
}
-module.exports = { parseCollectionYaml, safeFileOperation };
\ No newline at end of file
+module.exports = { parseCollectionYaml, safeFileOperation };