[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6NSHF1NCZ95SGWRW886EKPH":3,"skill-same:01M6NSHF1NCZ95SGWRW886EKPH":63},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":6,"ownerHtmlUrl":47,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":48,"install":49,"resources":62},"01M6NSHF1NCZ95SGWRW886EKPH","csharp-console-app-menu",null,"Scaffold an interactive console menu for a .NET Generic Host BackgroundService (Worker). Use when creating or extending a console app that needs a numbered menu loop backed by a Dictionary\u003Cint, Func\u003CCancellationToken, Task>>. Triggers include: \"add a menu option\", \"create a Worker with a menu\", \"console app menu loop\", \"BackgroundService menu\".","mattonweb\u002Fai-assistant-foundry","mattonweb","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2309734?v=4","01M6NQYCY846TKYN2ZCRS71WQ7","Matt Johnson","01M6NQYD2NPAQEFVD8TW9W0SVX",1,"MIT","https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fcode-csharp-console\u002Fmattnebr\u002Fcsharp-console-app-menu\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"csharp","csharp console app menu","app","console","loop","option","interactive","use","task","worker","triggers","create","dictionary","host","add","with","for","scaffold","2026-11-10 10:12:30",false,"---\nname: csharp-console-app-menu\ndescription: 'Scaffold an interactive console menu for a .NET Generic Host BackgroundService (Worker). Use when creating or extending a console app that needs a numbered menu loop backed by a Dictionary\u003Cint, Func\u003CCancellationToken, Task>>. Triggers include: \"add a menu option\", \"create a Worker with a menu\", \"console app menu loop\", \"BackgroundService menu\".'\n---\n\n# Console App Menu (BackgroundService Pattern)\n\n## Pattern Overview\n\nThe menu is driven by a `Dictionary\u003Cint, Func\u003CCancellationToken, Task>>` populated in the constructor. The `ExecuteAsync` loop renders the menu, reads a number, and dispatches to the matching method. `GetMenuLabel` auto-generates display text from PascalCase method names, stripping the `Async` suffix and prepending `Run`.\n\n## Key Members\n\n| Member | Purpose |\n|---|---|\n| `_menuActions` | `Dictionary\u003Cint, Func\u003CCancellationToken, Task>>` — add one entry per menu item |\n| `RenderMenu()` | Iterates `_menuActions` ordered by key; calls `GetMenuLabel` per entry |\n| `GetMenuLabel(action)` | Strips `Async`, splits PascalCase, prepends `Run` |\n| `ExecuteAsync` | The main loop: clear → wait → render → read → dispatch |\n| `WaitAsync` | `Task.Delay(_delay, stoppingToken)` — 1-second pace buffer |\n\n## Adding a New Menu Option\n\n1. Register in constructor:\n```csharp\nthis._menuActions = new Dictionary\u003Cint, Func\u003CCancellationToken, Task>>\n{\n    { 1, this.GenerateFooAsync },\n    { 2, this.LoadBarAsync },\n    { 3, this.ExportBazAsync },\n    { 4, this.ProcessFooAsync },  \u002F\u002F \u003C-- new entry\n};\n```\n\n2. Implement the private method:\n```csharp\nprivate async Task ProcessFooAsync(CancellationToken stoppingToken)\n{\n    try\n    {\n        Console.WriteLine();\n        Console.WriteLine(\"=== Process Foo ===\");\n        Console.WriteLine();\n\n        var startTime = DateTime.UtcNow;\n\n        \u002F\u002F TODO: call orchestrator or service here\n        await this._fooService.RunAsync(stoppingToken);\n\n        var duration = DateTime.UtcNow - startTime;\n\n        Console.WriteLine($\"✓ Completed in {duration.TotalSeconds:F2} seconds\");\n        Console.WriteLine();\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"Process Foo failed: {ex.Message}\");\n        Console.WriteLine($\"Error details: {ex}\");\n        Console.WriteLine();\n    }\n\n    await this.WaitAsync(stoppingToken);\n}\n```\n\n## Boilerplate Worker Skeleton\n\n```csharp\npublic class Worker : BackgroundService\n{\n    private readonly TimeSpan _delay = TimeSpan.FromSeconds(1);\n    private readonly IHostApplicationLifetime _lifetime;\n    private readonly Dictionary\u003Cint, Func\u003CCancellationToken, Task>> _menuActions;\n\n    public Worker(IHostApplicationLifetime lifetime)\n    {\n        this._lifetime = lifetime;\n        this._menuActions = new Dictionary\u003Cint, Func\u003CCancellationToken, Task>>\n        {\n            { 1, this.GenerateFooAsync },\n            { 2, this.LoadBarAsync },\n            { 3, this.ExportBazAsync },\n        };\n    }\n\n    protected override async Task ExecuteAsync(CancellationToken stoppingToken)\n    {\n        while (!stoppingToken.IsCancellationRequested)\n        {\n            Console.Clear();\n            await this.WaitAsync(stoppingToken);\n            this.RenderMenu();\n\n            Console.Write(\"Enter the number: \");\n            string? input = Console.ReadLine();\n\n            if (!int.TryParse(input, out int choice))\n            {\n                Console.WriteLine(\"Invalid input. Press any key to try again...\");\n                Console.ReadKey();\n                continue;\n            }\n\n            if (choice == 0)\n            {\n                Console.WriteLine(\"Shutting down...\");\n                await this.WaitAsync(stoppingToken);\n                this._lifetime.StopApplication();\n                return;\n            }\n\n            if (this._menuActions.TryGetValue(choice, out var action))\n                await action(stoppingToken);\n            else\n                Console.WriteLine(\"Unknown option.\");\n\n            Console.WriteLine();\n            Console.WriteLine(\"Press any key to pick another option...\");\n            Console.ReadKey();\n            await Task.Delay(10, stoppingToken);\n        }\n    }\n\n    private void RenderMenu()\n    {\n        Console.WriteLine();\n        Console.WriteLine(\"=== CHOICES ====================================\");\n        Console.WriteLine();\n        Console.WriteLine(\"Choose which service you want to run:\");\n        Console.WriteLine();\n\n        foreach (var kvp in this._menuActions.OrderBy(k => k.Key))\n            Console.WriteLine($\"{kvp.Key}. {GetMenuLabel(kvp.Value)}\");\n\n        Console.WriteLine(\"0. Exit\");\n        Console.WriteLine();\n    }\n\n    private static string GetMenuLabel(Func\u003CCancellationToken, Task> action)\n    {\n        string name = action.Method.Name;\n        if (name.EndsWith(\"Async\", StringComparison.OrdinalIgnoreCase))\n            name = name[..^5];\n\n        string spaced = System.Text.RegularExpressions.Regex\n            .Replace(name, \"(?\u003C!^)([A-Z])\", \" $1\");\n\n        return spaced.StartsWith(\"Run \", StringComparison.OrdinalIgnoreCase)\n            ? spaced\n            : $\"Run {spaced}\";\n    }\n\n    private async Task WaitAsync(CancellationToken stoppingToken) =>\n        await Task.Delay(this._delay, stoppingToken);\n\n    \u002F\u002F --- Menu action methods ---\n\n    private async Task GenerateFooAsync(CancellationToken stoppingToken)\n    {\n        try\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"=== Generate Foo ===\");\n            Console.WriteLine();\n\n            var startTime = DateTime.UtcNow;\n            \u002F\u002F TODO: implement\n            var duration = DateTime.UtcNow - startTime;\n\n            Console.WriteLine($\"✓ Duration: {duration.TotalSeconds:F2} seconds\");\n            Console.WriteLine();\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Generate Foo failed: {ex.Message}\");\n            Console.WriteLine($\"Error details: {ex}\");\n        }\n\n        await this.WaitAsync(stoppingToken);\n    }\n\n    private async Task LoadBarAsync(CancellationToken stoppingToken)\n    {\n        try\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"=== Load Bar ===\");\n            Console.WriteLine();\n            \u002F\u002F TODO: implement\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Load Bar failed: {ex.Message}\");\n            Console.WriteLine($\"Error details: {ex}\");\n        }\n\n        await this.WaitAsync(stoppingToken);\n    }\n\n    private async Task ExportBazAsync(CancellationToken stoppingToken)\n    {\n        try\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"=== Export Baz ===\");\n            Console.WriteLine();\n            \u002F\u002F TODO: implement\n            Console.WriteLine(\"✓ Export completed.\");\n            Console.WriteLine();\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Export Baz failed: {ex.Message}\");\n            Console.WriteLine($\"Error details: {ex}\");\n        }\n\n        await this.WaitAsync(stoppingToken);\n    }\n}\n```\n\n## Conventions\n\n- Every menu action method must match the signature `Func\u003CCancellationToken, Task>`.\n- Wrap the body in `try\u002Fcatch` and print `ex.Message` + `ex` for full stack trace.\n- End every action with `await this.WaitAsync(stoppingToken)`.\n- Use `=== Section Header ===` for Console section titles.\n- Use `✓` prefix for success output lines.\n- Display timing with `$\"{duration.TotalSeconds:F2} seconds\"`.\n","# Console App Menu (BackgroundService Pattern)\n\n## Pattern Overview\n\nThe menu is driven by a `Dictionary\u003Cint, Func\u003CCancellationToken, Task>>` populated in the constructor. The `ExecuteAsync` loop renders the menu, reads a number, and dispatches to the matching method. `GetMenuLabel` auto-generates display text from PascalCase method names, stripping the `Async` suffix and prepending `Run`.\n\n## Key Members\n\n| Member | Purpose |\n|---|---|\n| `_menuActions` | `Dictionary\u003Cint, Func\u003CCancellationToken, Task>>` — add one entry per menu item |\n| `RenderMenu()` | Iterates `_menuActions` ordered by key; calls `GetMenuLabel` per entry |\n| `GetMenuLabel(action)` | Strips `Async`, splits PascalCase, prepends `Run` |\n| `ExecuteAsync` | The main loop: clear → wait → render → read → dispatch |\n| `WaitAsync` | `Task.Delay(_delay, stoppingToken)` — 1-second pace buffer |\n\n## Adding a New Menu Option\n\n1. Register in constructor:\n```csharp\nthis._menuActions = new Dictionary\u003Cint, Func\u003CCancellationToken, Task>>\n{\n    { 1, this.GenerateFooAsync },\n    { 2, this.LoadBarAsync },\n    { 3, this.ExportBazAsync },\n    { 4, this.ProcessFooAsync },  \u002F\u002F \u003C-- new entry\n};\n```\n\n2. Implement the private method:\n```csharp\nprivate async Task ProcessFooAsync(CancellationToken stoppingToken)\n{\n    try\n    {\n        Console.WriteLine();\n        Console.WriteLine(\"=== Process Foo ===\");\n        Console.WriteLine();\n\n        var startTime = DateTime.UtcNow;\n\n        \u002F\u002F TODO: call orchestrator or service here\n        await this._fooService.RunAsync(stoppingToken);\n\n        var duration = DateTime.UtcNow - startTime;\n\n        Console.WriteLine($\"✓ Completed in {duration.TotalSeconds:F2} seconds\");\n        Console.WriteLine();\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"Process Foo failed: {ex.Message}\");\n        Console.WriteLine($\"Error details: {ex}\");\n        Console.WriteLine();\n    }\n\n    await this.WaitAsync(stoppingToken);\n}\n```\n\n## Boilerplate Worker Skeleton\n\n```csharp\npublic class Worker : BackgroundService\n{\n    private readonly TimeSpan _delay = TimeSpan.FromSeconds(1);\n    private readonly IHostApplicationLifetime _lifetime;\n    private readonly Dictionary\u003Cint, Func\u003CCancellationToken, Task>> _menuActions;\n\n    public Worker(IHostApplicationLifetime lifetime)\n    {\n        this._lifetime = lifetime;\n        this._menuActions = new Dictionary\u003Cint, Func\u003CCancellationToken, Task>>\n        {\n            { 1, this.GenerateFooAsync },\n            { 2, this.LoadBarAsync },\n            { 3, this.ExportBazAsync },\n        };\n    }\n\n    protected override async Task ExecuteAsync(CancellationToken stoppingToken)\n    {\n        while (!stoppingToken.IsCancellationRequested)\n        {\n            Console.Clear();\n            await this.WaitAsync(stoppingToken);\n            this.RenderMenu();\n\n            Console.Write(\"Enter the number: \");\n            string? input = Console.ReadLine();\n\n            if (!int.TryParse(input, out int choice))\n            {\n                Console.WriteLine(\"Invalid input. Press any key to try again...\");\n                Console.ReadKey();\n                continue;\n            }\n\n            if (choice == 0)\n            {\n                Console.WriteLine(\"Shutting down...\");\n                await this.WaitAsync(stoppingToken);\n                this._lifetime.StopApplication();\n                return;\n            }\n\n            if (this._menuActions.TryGetValue(choice, out var action))\n                await action(stoppingToken);\n            else\n                Console.WriteLine(\"Unknown option.\");\n\n            Console.WriteLine();\n            Console.WriteLine(\"Press any key to pick another option...\");\n            Console.ReadKey();\n            await Task.Delay(10, stoppingToken);\n        }\n    }\n\n    private void RenderMenu()\n    {\n        Console.WriteLine();\n        Console.WriteLine(\"=== CHOICES ====================================\");\n        Console.WriteLine();\n        Console.WriteLine(\"Choose which service you want to run:\");\n        Console.WriteLine();\n\n        foreach (var kvp in this._menuActions.OrderBy(k => k.Key))\n            Console.WriteLine($\"{kvp.Key}. {GetMenuLabel(kvp.Value)}\");\n\n        Console.WriteLine(\"0. Exit\");\n        Console.WriteLine();\n    }\n\n    private static string GetMenuLabel(Func\u003CCancellationToken, Task> action)\n    {\n        string name = action.Method.Name;\n        if (name.EndsWith(\"Async\", StringComparison.OrdinalIgnoreCase))\n            name = name[..^5];\n\n        string spaced = System.Text.RegularExpressions.Regex\n            .Replace(name, \"(?\u003C!^)([A-Z])\", \" $1\");\n\n        return spaced.StartsWith(\"Run \", StringComparison.OrdinalIgnoreCase)\n            ? spaced\n            : $\"Run {spaced}\";\n    }\n\n    private async Task WaitAsync(CancellationToken stoppingToken) =>\n        await Task.Delay(this._delay, stoppingToken);\n\n    \u002F\u002F --- Menu action methods ---\n\n    private async Task GenerateFooAsync(CancellationToken stoppingToken)\n    {\n        try\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"=== Generate Foo ===\");\n            Console.WriteLine();\n\n            var startTime = DateTime.UtcNow;\n            \u002F\u002F TODO: implement\n            var duration = DateTime.UtcNow - startTime;\n\n            Console.WriteLine($\"✓ Duration: {duration.TotalSeconds:F2} seconds\");\n            Console.WriteLine();\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Generate Foo failed: {ex.Message}\");\n            Console.WriteLine($\"Error details: {ex}\");\n        }\n\n        await this.WaitAsync(stoppingToken);\n    }\n\n    private async Task LoadBarAsync(CancellationToken stoppingToken)\n    {\n        try\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"=== Load Bar ===\");\n            Console.WriteLine();\n            \u002F\u002F TODO: implement\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Load Bar failed: {ex.Message}\");\n            Console.WriteLine($\"Error details: {ex}\");\n        }\n\n        await this.WaitAsync(stoppingToken);\n    }\n\n    private async Task ExportBazAsync(CancellationToken stoppingToken)\n    {\n        try\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"=== Export Baz ===\");\n            Console.WriteLine();\n            \u002F\u002F TODO: implement\n            Console.WriteLine(\"✓ Export completed.\");\n            Console.WriteLine();\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Export Baz failed: {ex.Message}\");\n            Console.WriteLine($\"Error details: {ex}\");\n        }\n\n        await this.WaitAsync(stoppingToken);\n    }\n}\n```\n\n## Conventions\n\n- Every menu action method must match the signature `Func\u003CCancellationToken, Task>`.\n- Wrap the body in `try\u002Fcatch` and print `ex.Message` + `ex` for full stack trace.\n- End every action with `await this.WaitAsync(stoppingToken)`.\n- Use `=== Section Header ===` for Console section titles.\n- Use `✓` prefix for success output lines.\n- Display timing with `$\"{duration.TotalSeconds:F2} seconds\"`.\n",{"name":5,"description":7},"main","d8518247cb8ab8b2dac57a6be33543ffd23b97c5","code-csharp-console\u002Fmattnebr\u002Fcsharp-console-app-menu",0,"https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry","https:\u002F\u002Fgithub.com\u002Fmattonweb","2026-05-29 08:42:23",{"source":8,"skillName":5,"commands":50,"prompt":60,"zipAvailable":61},[51,54,57],{"tool":52,"command":53},"npx","npx skills add mattonweb\u002Fai-assistant-foundry --skill csharp-console-app-menu",{"tool":55,"command":56},"bunx","bunx skills add mattonweb\u002Fai-assistant-foundry --skill csharp-console-app-menu",{"tool":58,"command":59},"pnpm","pnpm dlx skills add mattonweb\u002Fai-assistant-foundry --skill csharp-console-app-menu","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fcode-csharp-console\u002Fmattnebr\u002Fcsharp-console-app-menu\u002FSKILL.md",true,[],[64,99,113,133,154,179],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":80,"publishedAt":37},"01M6P02DENRHN6KVGYC55FKASJ","writing-clearly-and-concisely","Use when writing prose humans will read—documentation, commit messages, error messages, explanations, reports, or UI text. Applies Strunk's timeless rules for clearer, stronger, more professional writing.","https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fwrite-technical\u002Fsoftaworks\u002Fwriting-clearly-and-concisely\u002FSKILL.md",[70,75],{"categoryNo":71,"categoryName":72,"taxonomyType":73,"taxonomyTypeDesc":74},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[81,82,83,84,35,85,86,87,88,89,90,26,91,92,93,94,95,96,97,98],"writing clearly and concisely","writing","concisely","text","more","timeless","error","professional","prose","reports","read","Rules","commit messages","messages","error messages","ui","documentation","commit",{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":37},"01M6P0286HZ8RWMFCCPC8HF7SC","crafting-effective-readmes","Use when writing or improving README files. Not all READMEs are the same — provides templates and guidance matched to your audience and project type.","https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fwrite-technical\u002Fsoftaworks\u002Fcrafting-effective-readmes\u002FSKILL.md",[],[106,107,82,108,109,26,110,111,112],"crafting effective readmes","README","templates","type","project","guidance","files",{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":122,"publishedAt":37},"01M6P025A41BBTPWVTZ3GFQVG6","wiki-architect","You are a documentation architect that produces structured wiki catalogues and onboarding guides from codebases.","https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fwrite-technical\u002Fsickn33\u002Fwiki-architect\u002FSKILL.md",[119],{"categoryNo":120,"categoryName":121,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000038","人力资源",[123,124,125,126,127,128,129,130,131,132,97],"wiki","architect","wiki architect","unknown","you","documentation architect","guides","structured","community","onboarding",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":139,"publishedAt":37},"01M6P01NSKPXP77NWB4K0PXRK5","readme","You are an expert technical writer creating comprehensive project documentation. Your goal is to write a README.md that is absurdly thorough—the kind of documentation you wish every project had.","https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fwrite-technical\u002Fsickn33\u002Freadme\u002FSKILL.md",[],[107,140,141,142,127,143,144,110,145,146,42,147,148,149,150,151,97,152,153],"project documentation","tree","kind","expert","github","wish","writer","goal","write","technical writer","technical","https","write a readme","safe",{"skillNo":155,"name":156,"nameZh":6,"description":157,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":158,"categories":159,"keywords":160,"publishedAt":37},"01M6P01GP0NEN8KT3A3SA6ZFVE","ubiquitous-language","Extract a DDD-style ubiquitous language glossary from the current conversation, flagging ambiguities and proposing canonical terms. Saves to UBIQUITOUS_LANGUAGE.md. Use when user wants to define domain terms, build a glossary, harden terminology, create a ubiquitous language, or mentions \"domain model\" or \"DDD\".","https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fwrite-technical\u002Fmattpocock\u002Fubiquitous-language\u002FSKILL.md",[],[161,162,26,163,164,165,166,167,168,30,169,170,171,172,173,174,175,176,177,178],"ubiquitous language","language","extract","user","glossary","model","terms","ddd","build","true","canonical","style","define","harden","domain model","domain","terminology","conversation",{"skillNo":180,"name":181,"nameZh":6,"description":182,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":183,"categories":184,"keywords":187,"publishedAt":37},"01M6P01BJBP9XP4TDRT7QD1ZVA","technical-writing-style","Enforce clear, direct writing in software development documents including OKRs, PRDs, tech specs, architecture decision records (ADRs), git commit messages, PR descriptions, READMEs, changelogs, runbooks, incident postmortems, API docs, and onboarding guides. Trigger whenever a user asks to write, edit, revise, or review any of these document types. Also trigger when the user says writing \"sounds like AI\", \"feels robotic\", \"needs polish\", or asks to \"make it sound more natural\" in the context of technical or professional prose. Do not trigger for fiction, poetry, creative writing, academic papers, or legal documents unless the user explicitly asks for a more natural tone.","https:\u002F\u002Fgithub.com\u002Fmattonweb\u002Fai-assistant-foundry\u002Fblob\u002Fmain\u002Fwrite-technical\u002Fmattnebr\u002Ftechnical-writing-style\u002FSKILL.md",[185,186],{"categoryNo":71,"categoryName":72,"taxonomyType":73,"taxonomyTypeDesc":74},{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},[188,189,172,150,82,190,88,191,192,193,194,195,196,197,198,94,199,200,98,201],"writing style","technical writing style","technical writing","papers","types","runbooks","software development","incident","Poetry","decision","api","documents","architecture","review"]