From 5120247eb08a24880aa3434775ea2e7748623ac0 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 15:53:25 +0200 Subject: [PATCH 01/14] =?UTF-8?q?=F0=9F=99=88=20add=20bot=20workspace=20to?= =?UTF-8?q?=20gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Projects using .bot/ folder for local agentic workspaces and ephemeral state should not leak those artifacts into source control. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index a2986b7..7ad005c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ skills/*-workspace/ **/outputs/ **/timing.json **/grades.json + +# Bot workspace (local-only AI agent ideation, PRDs, and agentic loop state) +.bot/* \ No newline at end of file From 821a3e48532f9cc51625f4c79c08a120b406a653 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 15:53:38 +0200 Subject: [PATCH 02/14] =?UTF-8?q?=E2=9C=A8=20add=20git-story-teller=20skil?= =?UTF-8?q?l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce deterministic repository story generation workflow. The skill bundles a .NET file-based context generator (scripts/story.cs) that clones a repository, discovers package targets, extracts deterministic evidence using repomix, and writes manifest, instructions, and context files. The agent then uses that evidence to write target stories before generating the overview, enforcing grounding, context-budget awareness, and no-invention rules. --- skills/git-story-teller/SKILL.md | 205 +++++ skills/git-story-teller/agents/openai.yaml | 4 + skills/git-story-teller/evals/evals.json | 15 + skills/git-story-teller/scripts/story.cs | 900 +++++++++++++++++++++ 4 files changed, 1124 insertions(+) create mode 100644 skills/git-story-teller/SKILL.md create mode 100644 skills/git-story-teller/agents/openai.yaml create mode 100644 skills/git-story-teller/evals/evals.json create mode 100644 skills/git-story-teller/scripts/story.cs diff --git a/skills/git-story-teller/SKILL.md b/skills/git-story-teller/SKILL.md new file mode 100644 index 0000000..668f2e5 --- /dev/null +++ b/skills/git-story-teller/SKILL.md @@ -0,0 +1,205 @@ +--- +name: git-story-teller +description: > + Generate source-grounded repository story markdown from deterministic ContentSync context bundles. Use when the user asks to create, refresh, or complete repo/package stories, family or project overview pages, .bot/stories output, ContentSync story workflows, or result/Index.md plus result/{TargetName}.md files for any repository URL. The skill runs its bundled .NET file-based context generator, writes target stories first, then writes the overview from completed target stories, and enforces grounding, context-budget, and no-invention rules. +--- + +# Git Story Teller + +Use this skill to turn a deterministic story workspace into website-ready or docs-ready Markdown. The bundled `scripts/story.cs` runner owns repository access, evidence gathering, target discovery, context packing, and generated instructions. The agent owns reading that evidence, writing the story files, and validating that every claim is grounded. + +## Critical + +- Treat generated output as the source of truth. If `manifest.json`, `instructions.md`, or `*.context.md` files disagree with this skill, follow the generated files unless they are internally inconsistent. +- Keep the workflow generic. The runner input is a full repository URL, not an implied owner/slug convention. +- Require both `--repo-url` and `--output-root`. Do not invent defaults silently. +- If a `.bot` folder exists in the workspace the agent is working from, recommend `/.bot/stories` as the output root. +- Do not make `repo-id` customizable. It is derived from the final repository URL path segment. +- Do not make the result directory customizable. It is always `result`. +- Do not assume GitHub owner, repository host, organization, package prefix, website path, or docs domain from memory. +- Do not call an LLM provider from the runner. The calling agent is the brain that writes prose. +- Process one target context at a time. Do not load all target contexts into the same prompt unless the generated manifest explicitly requires it. +- Write target result files before the overview result file. +- Do not invent APIs, target relationships, examples, dependencies, support statements, performance claims, or architectural claims not supported by the target context. +- If required deterministic files are missing, stale, contradictory, or too large to use safely, stop and report the blocking issue instead of guessing. +- Do not copy results into a website or documentation tree unless the user explicitly asks for publication or sync. + +## Runner Contract + +The skill bundles a .NET 10 file-based app: + +```text +scripts/story.cs +``` + +Run it with `dotnet run --file` so it is not confused with a nearby project file: + +```powershell +dotnet run --file /scripts/story.cs -- --repo-url --output-root +``` + +Required inputs: + +```text +--repo-url Fully qualified git repository URL +--output-root Directory where the story workspace will be written +``` + +Fixed conventions: + +```text +repo-id Derived from the final repository URL path segment, with .git removed +result dir result +``` + +The runner requires the .NET 10 SDK or newer, `git`, and `npx`/repomix access. If these are unavailable, stop and report the missing dependency. + +## Expected Workspace + +The story root is chosen by the caller. For repositories that already use `.bot`, recommend: + +```text +.bot/stories +``` + +Generated shape: + +```text +{output-root}/{repo-id}/ + manifest.json + instructions.md + overview.context.md + {TargetName}.context.md + result/ + Index.md + {TargetName}.md +``` + +The manifest is authoritative after generation. Always follow the manifest for concrete target names, context paths, result paths, and phase order. + +## Workflow + +### Step 1: Resolve Inputs + +Collect or infer only these two runner inputs: + +- `repo-url`: required. Ask for it if the user gives only a slug or a repository nickname. +- `output-root`: required. If the active workspace has a `.bot` directory, recommend `/.bot/stories`; otherwise ask for the path. + +Do not ask for `repo-id` or result directory. If two repositories would collide because they share the same final URL path segment, ask the user for a different `output-root`. + +### Step 2: Generate or Locate the Story Workspace + +If the user points to an existing `{output-root}/{repo-id}` folder, inspect it first. + +If the workspace does not exist or the user asks to regenerate context, run the bundled runner from this skill: + +```powershell +dotnet run --file /scripts/story.cs -- --repo-url --output-root +``` + +The runner writes deterministic context files and creates the `result` folder. It does not call an LLM and does not overwrite existing `result/*.md` files. + +### Step 3: Read the Run Contract + +Read only these root files first: + +```text +manifest.json +instructions.md +``` + +From `manifest.json`, identify: + +- repository URL +- repository identifier +- output directory +- target phase entries +- overview phase entry +- each context file path +- each result file path +- dependency order + +If there is no manifest, infer the target list only from `*.context.md` files and stop to tell the user the manifest is missing. Continue only if the user explicitly accepts the degraded workflow. + +### Step 4: Write Target Stories + +For each target in the first phase: + +1. Open only that target's context file plus `instructions.md` if needed. +2. Confirm the target result path is `result/{TargetName}.md` or the manifest's declared equivalent. +3. Write the exact required sections from the generated context. +4. Ground API lists and examples in source, tests, project files, README files, or metadata found in the context. +5. Keep examples compact and use real namespaces, type names, method names, and constructor signatures from the context. +6. If the context proves the target is a convenience, aggregate, or metadata-only package with no source of its own, write that honestly instead of inventing APIs. + +Do not use another target's context to fill gaps unless the current context explicitly includes it or the manifest marks that relationship as required. + +### Step 5: Write the Overview + +Write `result/Index.md` only after target stories exist. + +Use the overview context and the completed target result files as the main editorial input. The overview should help readers choose between targets or understand the repository's shape. It should not repeat every target page or amplify unsupported claims. + +If any target story is missing, decide from the manifest: + +- If the overview depends on all target stories, stop and report the missing files. +- If partial overview generation is explicitly allowed, name the missing target stories in the final response. + +### Step 6: Validate Grounding and Shape + +Before finishing, verify: + +- Every manifest target has a corresponding result file. +- `result/Index.md` exists when the manifest includes an overview target. +- Result filenames match manifest paths. +- Required headings from the generated context are present verbatim. +- No result file contains analysis notes, citations, XML, JSON, confidence scores, or chat commentary unless the generated prompt explicitly asks for them. +- Code examples mention only APIs visible in the relevant context. +- Target stories do not make broad claims such as robust, seamless, powerful, or comprehensive unless immediately grounded in concrete evidence. + +Use targeted searches instead of rereading everything: + +```powershell +rg -n "TODO|TBD|confidence|citation|analysis notes|I cannot|as an AI" /result +rg -n "robust|seamless|powerful|comprehensive" /result +``` + +Explain any remaining risk, especially missing tests, ambiguous APIs, oversized context, or targets whose purpose is unclear from source. + +## Context Budget Rules + +- Open target contexts one at a time. +- Prefer manifest summaries, target result files, and overview context for the overview instead of reopening every target context. +- If a single target context is too large for the active model, split the work by evidence type: project metadata first, public source second, tests third, README last. +- Never silently omit evidence because it is large. State the limitation and use the generated instructions to choose the smallest safe subset. + +## Publication + +The story workspace is staging output. A consuming website or docs system may map staged files into its own content tree. For the current Codebelt website, the conventional mapping is: + +```text +src/Codebelt.Website.WebApp/Content/Markdown/{repo-id}/Index.md +src/Codebelt.Website.WebApp/Content/Markdown/{repo-id}/{TargetName}.md +``` + +Do not copy staged results there unless the user asks for website sync, publication, or integration. + +## Good Output Characteristics + +- Target pages are concrete, source-backed, and useful to experienced developers. +- The overview explains target selection, repository boundaries, and relationships. +- The writing is restrained and developer-facing, not marketing-heavy. +- The agent follows the generated manifest instead of improvising the run order. +- The final response names the result files written and any validation gaps. + +## Bad Output Characteristics + +- Running a separate ContentSync project instead of the bundled `scripts/story.cs` runner. +- Choosing provider/model/reasoning flags from memory. +- Passing only a repository slug when the runner requires a full URL. +- Assuming a fixed organization such as `codebeltnet` or a fixed repository host such as GitHub. +- Loading the entire repository context for every target story. +- Writing `Index.md` before target stories exist. +- Inventing usage examples from plausible framework patterns rather than supplied source and tests. +- Copying staged files into website content without an explicit user request. \ No newline at end of file diff --git a/skills/git-story-teller/agents/openai.yaml b/skills/git-story-teller/agents/openai.yaml new file mode 100644 index 0000000..096d425 --- /dev/null +++ b/skills/git-story-teller/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Git Story Teller" + short_description: "Write grounded repo stories from ContentSync bundles." + default_prompt: "Use git-story-teller to generate source-grounded target stories and an overview from a generic ContentSync story workspace." \ No newline at end of file diff --git a/skills/git-story-teller/evals/evals.json b/skills/git-story-teller/evals/evals.json new file mode 100644 index 0000000..cfbba39 --- /dev/null +++ b/skills/git-story-teller/evals/evals.json @@ -0,0 +1,15 @@ +{ + "skill_name": "git-story-teller", + "evals": [ + { + "id": "eval-target-first-story-workspace", + "prompt": "Use git-story-teller to complete stories for an existing generated workspace at .bot/stories/example-project. The workspace has manifest.json, instructions.md, target context files, overview.context.md, and an empty result folder.", + "expected_output": "Inspects manifest.json and instructions.md first, writes target result files under result/{TargetName}.md before result/Index.md, processes one target context at a time, treats generated output as source of truth, follows PACKAGE STORY PROMPT and OVERVIEW STORY PROMPT sections, and reports validation gaps without copying files into a website content tree unless explicitly asked." + }, + { + "id": "eval-generate-deterministic-context-full-url", + "prompt": "Use git-story-teller to generate story context for https://github.com/example/project and then write the target stories and overview. The current workspace contains a .bot folder.", + "expected_output": "Recommends .bot/stories as the required output root, runs or proposes dotnet run --file /scripts/story.cs with --repo-url and --output-root, avoids provider/model/reasoning LLM options, refuses slug-only hardcoded organization assumptions, does not ask for repo-id or result-dir, then follows the generated manifest and prompt sections to write result/Index.md and result/{TargetName}.md files." + } + ] +} \ No newline at end of file diff --git a/skills/git-story-teller/scripts/story.cs b/skills/git-story-teller/scripts/story.cs new file mode 100644 index 0000000..ca856dc --- /dev/null +++ b/skills/git-story-teller/scripts/story.cs @@ -0,0 +1,900 @@ +#:property TargetFramework=net10.0 +#:property Nullable=enable +#:property LangVersion=latest +#:property PublishAot=false + +using System.Diagnostics; +using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Xml.Linq; + +return await StoryScript.RunAsync(args); + +internal static class StoryScript +{ + private const string ResultDirectoryName = "result"; + + public static async Task RunAsync(string[] args) + { + if (args.Length == 0 || HasFlag(args, "--help") || HasFlag(args, "-h")) + { + PrintUsage(); + return 0; + } + + try + { + var options = ParseOptions(args); + var repoId = DeriveRepoId(options.RepoUrl); + var workspace = Path.GetFullPath(Path.Combine(options.OutputRoot, repoId)); + var resultDir = Path.Combine(workspace, ResultDirectoryName); + + Directory.CreateDirectory(workspace); + Directory.CreateDirectory(resultDir); + + Console.WriteLine($"[story] repo-url={options.RepoUrl}"); + Console.WriteLine($"[story] output-root={options.OutputRoot}"); + Console.WriteLine($"[story] repo-id={repoId}"); + Console.WriteLine(); + + var tempRoot = Path.Combine(Path.GetTempPath(), "git-story-teller-" + Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempRoot); + + try + { + var cloneDir = Path.Combine(tempRoot, "repo"); + await CloneRepositoryAsync(options.RepoUrl, cloneDir); + + var targets = DiscoverTargets(cloneDir); + Console.WriteLine($"[story] discovered {targets.Count} target(s)"); + + var targetEntries = new List(); + foreach (var target in targets) + { + var contextFileName = target.Name + ".context.md"; + var resultPath = Path.Combine(ResultDirectoryName, target.Name + ".md").Replace('\\', '/'); + var context = await BuildTargetContextAsync(options.RepoUrl, cloneDir, target); + await WriteUtf8Async(Path.Combine(workspace, contextFileName), context); + + targetEntries.Add(new TargetManifestEntry( + "package", + target.Name, + contextFileName, + resultPath)); + } + + var overviewContextName = "overview.context.md"; + var overviewContext = await BuildOverviewContextAsync(options.RepoUrl, cloneDir, repoId, targets); + await WriteUtf8Async(Path.Combine(workspace, overviewContextName), overviewContext); + + await WriteUtf8Async(Path.Combine(workspace, "instructions.md"), BuildInstructions(options.RepoUrl, repoId)); + await WriteManifestAsync( + Path.Combine(workspace, "manifest.json"), + options, + repoId, + workspace, + targetEntries, + overviewContextName); + + Console.WriteLine(); + Console.WriteLine("[story] deterministic workspace written:"); + Console.WriteLine(" " + workspace); + Console.WriteLine("[story] result files are agent-authored and were not overwritten."); + return 0; + } + finally + { + TryDeleteDirectory(tempRoot); + } + } + catch (Exception ex) + { + Console.Error.WriteLine("Error: " + ex.Message); + return 1; + } + } + + private static StoryOptions ParseOptions(string[] args) + { + var repoUrl = GetOption(args, "--repo-url"); + var outputRoot = GetOption(args, "--output-root"); + + if (string.IsNullOrWhiteSpace(repoUrl)) + { + throw new InvalidOperationException("Missing required option --repo-url."); + } + + if (string.IsNullOrWhiteSpace(outputRoot)) + { + throw new InvalidOperationException("Missing required option --output-root."); + } + + ValidateRepositoryUrl(repoUrl); + return new StoryOptions(repoUrl.Trim(), Path.GetFullPath(outputRoot.Trim())); + } + + private static string? GetOption(string[] args, string name) + { + var index = Array.IndexOf(args, name); + return index >= 0 && index + 1 < args.Length ? args[index + 1] : null; + } + + private static bool HasFlag(string[] args, string name) => Array.IndexOf(args, name) >= 0; + + private static void ValidateRepositoryUrl(string repoUrl) + { + if (!Uri.TryCreate(repoUrl, UriKind.Absolute, out var uri)) + { + throw new InvalidOperationException("--repo-url must be a fully qualified repository URL."); + } + + if (uri.Scheme is not ("http" or "https" or "ssh" or "git")) + { + throw new InvalidOperationException("--repo-url must use http, https, ssh, or git scheme."); + } + } + + private static string DeriveRepoId(string repoUrl) + { + var uri = new Uri(repoUrl); + var path = uri.AbsolutePath.Trim('/'); + if (string.IsNullOrWhiteSpace(path)) + { + throw new InvalidOperationException("Could not derive repo id because --repo-url has no path segment."); + } + + var lastSegment = path.Split('/', StringSplitOptions.RemoveEmptyEntries).Last(); + if (lastSegment.EndsWith(".git", StringComparison.OrdinalIgnoreCase)) + { + lastSegment = lastSegment[..^4]; + } + + var sanitized = Regex.Replace(lastSegment, "[^A-Za-z0-9._-]", "-").Trim('-', '.', '_'); + if (string.IsNullOrWhiteSpace(sanitized)) + { + throw new InvalidOperationException("Could not derive a filesystem-safe repo id from --repo-url."); + } + + return sanitized.ToLowerInvariant(); + } + + private static async Task CloneRepositoryAsync(string repoUrl, string cloneDir) + { + Console.WriteLine("[story] cloning repository for discovery..."); + await RunProcessAsync("git", ["clone", "--depth", "1", repoUrl, cloneDir], Directory.GetCurrentDirectory()); + } + + private static IReadOnlyList DiscoverTargets(string cloneDir) + { + var srcDir = Path.Combine(cloneDir, "src"); + if (!Directory.Exists(srcDir)) + { + return []; + } + + var projectFiles = Directory.EnumerateFiles(srcDir, "*.csproj", SearchOption.AllDirectories) + .OrderBy(p => Path.GetRelativePath(cloneDir, p), StringComparer.OrdinalIgnoreCase) + .ToList(); + + var targets = new List(); + foreach (var projectFile in projectFiles) + { + var metadata = ReadProjectMetadata(projectFile); + if (metadata.IsPackable is false) + { + continue; + } + + var name = FirstNonEmpty( + metadata.PackageId, + metadata.AssemblyName, + Path.GetFileNameWithoutExtension(projectFile)); + + var sourceDir = Path.GetDirectoryName(projectFile) + ?? throw new InvalidOperationException($"Could not resolve source directory for '{projectFile}'."); + + var testDir = FindTestDirectory(cloneDir, projectFile, name); + var sourceFiles = Directory.EnumerateFiles(sourceDir, "*.cs", SearchOption.AllDirectories) + .Where(p => !IsUnderDirectoryName(p, "bin") && !IsUnderDirectoryName(p, "obj")) + .ToList(); + + targets.Add(new TargetInfo( + name, + Path.GetRelativePath(cloneDir, sourceDir).Replace('\\', '/'), + testDir is null ? null : Path.GetRelativePath(cloneDir, testDir).Replace('\\', '/'), + sourceFiles.Count == 0, + metadata.BundledPackages)); + } + + return targets; + } + + private static ProjectMetadata ReadProjectMetadata(string projectFile) + { + var doc = XDocument.Load(projectFile, LoadOptions.PreserveWhitespace); + var packageId = ElementValue(doc, "PackageId"); + var assemblyName = ElementValue(doc, "AssemblyName"); + var isPackableText = ElementValue(doc, "IsPackable"); + bool? isPackable = null; + if (!string.IsNullOrWhiteSpace(isPackableText) && bool.TryParse(isPackableText, out var parsed)) + { + isPackable = parsed; + } + + var bundledPackages = doc.Descendants() + .Where(e => e.Name.LocalName is "PackageReference" or "ProjectReference") + .Select(e => e.Attribute("Include")?.Value) + .Where(v => !string.IsNullOrWhiteSpace(v)) + .Select(v => v!) + .Distinct(StringComparer.OrdinalIgnoreCase) + .OrderBy(v => v, StringComparer.OrdinalIgnoreCase) + .ToList(); + + return new ProjectMetadata(packageId, assemblyName, isPackable, bundledPackages); + } + + private static string ElementValue(XDocument doc, string localName) => + doc.Descendants().FirstOrDefault(e => e.Name.LocalName == localName)?.Value.Trim() ?? string.Empty; + + private static string FirstNonEmpty(params string[] values) => + values.First(v => !string.IsNullOrWhiteSpace(v)).Trim(); + + private static string? FindTestDirectory(string cloneDir, string sourceProjectFile, string targetName) + { + var testRoots = new[] { "test", "tests" } + .Select(r => Path.Combine(cloneDir, r)) + .Where(Directory.Exists) + .ToList(); + + foreach (var root in testRoots) + { + var testProjects = Directory.EnumerateFiles(root, "*.csproj", SearchOption.AllDirectories) + .OrderBy(p => p, StringComparer.OrdinalIgnoreCase) + .ToList(); + + foreach (var testProject in testProjects) + { + if (ReferencesProject(testProject, sourceProjectFile)) + { + return Path.GetDirectoryName(testProject); + } + } + + var normalizedTarget = NormalizeForMatch(targetName); + var byName = testProjects.FirstOrDefault(p => NormalizeForMatch(Path.GetFileNameWithoutExtension(p)).Contains(normalizedTarget, StringComparison.OrdinalIgnoreCase)); + if (byName is not null) + { + return Path.GetDirectoryName(byName); + } + } + + return null; + } + + private static bool ReferencesProject(string testProjectFile, string sourceProjectFile) + { + var testProjectDir = Path.GetDirectoryName(testProjectFile) + ?? throw new InvalidOperationException($"Could not resolve project directory for '{testProjectFile}'."); + + var sourceFullPath = Path.GetFullPath(sourceProjectFile); + var doc = XDocument.Load(testProjectFile, LoadOptions.PreserveWhitespace); + foreach (var include in doc.Descendants().Where(e => e.Name.LocalName == "ProjectReference").Select(e => e.Attribute("Include")?.Value)) + { + if (string.IsNullOrWhiteSpace(include)) + { + continue; + } + + var referenced = Path.GetFullPath(Path.Combine(testProjectDir, include)); + if (string.Equals(referenced, sourceFullPath, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + + private static string NormalizeForMatch(string value) => + Regex.Replace(value, "[^A-Za-z0-9]", string.Empty).ToLowerInvariant(); + + private static bool IsUnderDirectoryName(string path, string directoryName) + { + var segments = Path.GetFullPath(path).Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + return segments.Any(s => string.Equals(s, directoryName, StringComparison.OrdinalIgnoreCase)); + } + + private static async Task BuildTargetContextAsync(string repoUrl, string cloneDir, TargetInfo target) + { + Console.WriteLine($"[story] packing context for {target.Name}..."); + + var includeParts = new List + { + "README.md", + "Directory.Build.props", + "Directory.Build.targets", + "Directory.Packages.props", + target.SourcePath + "/**" + }; + + if (!string.IsNullOrWhiteSpace(target.TestPath)) + { + includeParts.Add(target.TestPath + "/**"); + } + + includeParts.Add(".nuget/**/README.md"); + var repomix = await PackWithRepomixAsync(cloneDir, string.Join(',', includeParts)); + + var sb = new StringBuilder(); + AppendHeader(sb, "TARGET IDENTITY"); + sb.AppendLine($"Repository: {repoUrl}"); + sb.AppendLine($"Target: {target.Name}"); + sb.AppendLine("Kind: package"); + sb.AppendLine($"Source path: {target.SourcePath}"); + sb.AppendLine($"Test path: {target.TestPath ?? "(not discovered)"}"); + sb.AppendLine($"Metadata-only target: {target.IsConveniencePackage}"); + sb.AppendLine($"Result path: result/{target.Name}.md"); + sb.AppendLine(); + + if (target.BundledPackages.Count > 0) + { + AppendHeader(sb, "DECLARED REFERENCES"); + foreach (var package in target.BundledPackages) + { + sb.AppendLine("- " + package); + } + sb.AppendLine(); + } + + AppendHeader(sb, "PACKAGE STORY PROMPT"); + AppendMultiline(sb, BuildPackageStoryPrompt(target.Name)); + + AppendHeader(sb, "PACKED REPOSITORY CONTENT"); + sb.AppendLine(repomix.Trim()); + sb.AppendLine(); + + return sb.ToString(); + } + + private static async Task BuildOverviewContextAsync(string repoUrl, string cloneDir, string repoId, IReadOnlyList targets) + { + Console.WriteLine("[story] packing overview context..."); + var repomix = await PackWithRepomixAsync(cloneDir, "README.md,.nuget/**/README.md,Directory.Build.props,Directory.Build.targets,Directory.Packages.props,src/**/*.csproj"); + + var sb = new StringBuilder(); + AppendHeader(sb, "REPOSITORY IDENTITY"); + sb.AppendLine($"Repository: {repoUrl}"); + sb.AppendLine($"Repository id: {repoId}"); + sb.AppendLine($"Targets: {targets.Count}"); + sb.AppendLine("Result path: result/Index.md"); + sb.AppendLine(); + + AppendHeader(sb, "TARGET STORIES TO READ FIRST"); + if (targets.Count == 0) + { + sb.AppendLine("No package targets were discovered under src/. Write an overview only if the repository context is sufficient."); + } + else + { + foreach (var target in targets) + { + sb.AppendLine($"- {target.Name}: result/{target.Name}.md"); + } + } + sb.AppendLine(); + + AppendHeader(sb, "OVERVIEW STORY PROMPT"); + AppendMultiline(sb, BuildOverviewStoryPrompt(repoId, targets)); + + AppendHeader(sb, "SUPPLEMENTARY REPOSITORY CONTENT"); + sb.AppendLine(repomix.Trim()); + sb.AppendLine(); + + return sb.ToString(); + } + + private static string BuildInstructions(string repoUrl, string repoId) => + $$""" + # Story Writing Instructions + + Repository: {{repoUrl}} + Repository id: {{repoId}} + + The deterministic runner generated this workspace. The agent writes Markdown stories; this script does not call an LLM and does not overwrite result files. + + ## Contract + + - Treat `manifest.json` as authoritative for context and result paths. + - Process target contexts one at a time. + - Write every target result before writing the overview. + - Write target stories to `result/{TargetName}.md`. + - Write the overview to `result/Index.md`. + - Use the generated prompt sections in each `.context.md` file as the task contract. + - Do not invent APIs, package relationships, examples, dependencies, support statements, performance claims, or architectural claims. + - If context is missing, stale, contradictory, or too large to use safely, stop and report the blocker. + + ## Shared Editorial Rules + + {{BuildSharedEditorialRules()}} + + ## Suggested Order + + 1. Read `manifest.json`. + 2. Read this file. + 3. For each target in the `packages` phase, read its context and write its result file. + 4. Read `overview.context.md` and the completed target result files. + 5. Write `result/Index.md`. + 6. Validate that all manifest result paths exist. + """; + + private static string BuildSharedEditorialRules() => + """ + You are a senior .NET library documentation editor. + + Your job is to turn repository context into accurate, developer-facing Markdown documentation. + + Priorities, in order: + 1. Accuracy. + 2. Grounding in the supplied source, tests, project files, README files, and metadata. + 3. Clear ecosystem positioning. + 4. Concise, useful website or documentation copy. + 5. Polished but restrained language. + + Your reader is a professional .NET engineer. + They know .NET, NuGet, dependency injection, testing, hosting, ASP.NET Core, and common framework terminology. + They do not know this specific repository or package. + + Use source files to understand what the target exposes and owns. + Use test files to understand how consumers are expected to use the target. + Use project files to understand dependencies and package relationships. + Use README and metadata files as editorial context, but prefer source and tests when there is a conflict. + + You must not invent APIs, features, target relationships, dependencies, examples, use cases, or architectural claims not supported by the supplied context. + + Write with authority. + Be concrete. + Surface the non-obvious. + Respect the reader's intelligence. + Avoid marketing fluff. + Avoid vague claims such as "robust", "seamless", "powerful", "easy-to-use", or "comprehensive" unless the supplied evidence makes the claim specific. + + Style rules: + - Always include every required section heading verbatim on its own line, including the very first one. Never omit a heading. + - Do not use em dashes in prose. + - Do not use "Furthermore". + - Do not use "In conclusion". + - Do not use filler phrases. + - Keep the writing tight. + - Cut anything that does not add information. + - Final output must be Markdown only. + - Do not include analysis notes, confidence scores, citations, XML, JSON, or chat commentary unless the target prompt explicitly requests them. + """; + + private static string BuildPackageStoryPrompt(string targetName) => + $$""" + Write the documentation page for {{targetName}}. + + Output file: + `result/{{targetName}}.md` + + Audience: + Experienced .NET developers who are evaluating whether this NuGet package belongs in their project. + Assume they understand .NET, NuGet, dependency injection, testing, hosting, ASP.NET Core, and common framework terminology. + Do not explain basic .NET concepts. + + Grounding rules: + Use only the supplied target context. + Source files define the public API and package responsibility. + Test files show intended usage. + Project files show dependencies and package relationships. + XML documentation is evidence, but rewrite descriptions for clarity when needed. + README and metadata files may guide tone and positioning, but do not let them override source and tests. + Do not invent features, scenarios, dependencies, method names, constructor overloads, namespaces, return types, or package relationships. + Ignore internal implementation details unless they explain the public API. + Prefer public types, extension methods, options/configuration types, factories, abstractions, and test-visible usage patterns. + If the package has obsolete or deprecated APIs, do not present them as the recommended path. + If the package is metadata-only, aggregate, or convenience-only, say that clearly and do not invent public APIs. + + Before writing the final page, internally identify: + - the package's specific responsibility inside the repository + - the primary developer scenario + - the 3-5 public types that matter most to consumers + - the most representative usage pattern found in tests + - what this package deliberately does not solve + - any confidence risks caused by missing tests or unclear source + + Write exactly these sections. + + ## Overview + + 1-2 concise paragraphs. + Explain the specific responsibility this package owns. + If it extends another package in the same repository, name that package explicitly. + Be concrete. + Avoid generic phrases such as "provides utilities" unless the package is genuinely a utility package. + Do not oversell the package. + + ## Key APIs + + List the 3-5 most important public consumer-facing types, extension methods, options types, factories, abstractions, or helpers. + + Format each item exactly: + + `ApiName` - Description. + + Rules: + - Mention only APIs visible in the supplied source. + - Prefer APIs that a consumer would directly inherit from, instantiate, configure, call, or implement. + - Descriptions should explain practical role, not merely repeat generic XML documentation wording. + - Do not include incidental internal helpers, test-only types, or implementation details. + - If fewer than 3 important public APIs exist, list fewer. + + ## Basic usage + + Write one complete C# example that demonstrates the package's central usage pattern from a consumer's point of view. + + Rules: + - The example may be newly written for documentation. + - It must be grounded in the supplied source files and tests. + - Use tests to understand intended behavior, common setup, required constructor arguments, and expected usage flow. + - Do not copy awkward regression tests, edge-case tests, silly sample values, or maintainer-internal namespaces unless they are the clearest documentation example. + - Prefer a happy-path example unless an error path is the most important pattern. + - Prefer a consumer namespace such as `MyProject.Tests` unless the original namespace is required for compilation. + - The example should demonstrate at least two central package features when possible. + - Avoid examples where the domain object is more prominent than the package itself. + - Use real namespaces, real type names, real method calls, and real constructor signatures from the supplied content. + - Do not invent APIs, overloads, extension methods, options, return types, helper methods, or setup that are not supported by the supplied content. + - Keep it between 10 and 20 lines when feasible. + - Use a ```csharp fenced code block. + - Do not include ellipses, pseudocode, placeholders, or unexplained magic. + - Do not override lifecycle or cleanup hooks unless the example cleans up a real resource or demonstrates lifecycle behavior as the main point. + + After the code block, write exactly 2 sentences: + 1. When to use this pattern. + 2. Why it matters. + + ## Installation + + ```bash + dotnet add package {{targetName}} + ``` + + ## Usage guidance + + One honest paragraph. + Explain when plain framework APIs, a lower-level package, a sibling package, or no package at all would be a better choice. + Do not insult the package. + Do not oversell it. + """; + + private static string BuildOverviewStoryPrompt(string repoId, IReadOnlyList targets) + { + var targetList = targets.Count == 0 + ? "- No package targets discovered." + : string.Join(Environment.NewLine, targets.Select(t => "- " + t.Name)); + + return $$""" + Write the overview page for this repository. + + Output file: + `result/Index.md` + + Primary editorial context: + Read the completed target stories before writing this page: + {{targetList}} + + Audience: + Experienced .NET developers who need a mental model before choosing an individual package or target from this repository. + Assume they understand .NET, NuGet, dependency injection, testing, hosting, ASP.NET Core, and common framework terminology. + Do not explain basic .NET concepts. + + Grounding rules: + The completed target stories are the primary editorial context. + Supplementary README, package README, project, dependency, and metadata information may be used to clarify relationships. + Do not invent package purposes, dependencies, recommended installation paths, scenarios, APIs, or architectural claims. + Do not amplify unsupported claims from a target story. + Prefer concrete responsibilities and decision guidance over marketing language. + Keep the overview focused on how developers should understand and choose between the targets. + + Before writing the final page, internally identify: + - the unifying purpose of the repository + - the foundation package or primary target, if one exists + - optional add-on packages, if any exist + - convenience or meta packages, if any exist + - the recommended starting point + - scenarios where installing or using less is better + - the one non-obvious insight developers should understand + + Write exactly these three sections. + + ## Overview + + Start with 2-3 sentences that explain the unifying purpose across the targets. + Make clear what kind of developer problem this repository solves. + Do not use broad marketing language. + + After the opening sentences, include a compact target selection table. + + Columns: + + | Scenario | Target | + |---|---| + + Rules: + - Each row must map a concrete developer scenario to one or more target names. + - Keep the scenarios practical and non-overlapping. + - Prefer fewer, sharper rows over exhaustive rows. + - Do not create separate rows for scenarios that are effectively the same decision. + - Include convenience or aggregate targets only if they exist and their role is clear. + - Avoid internal phrasing unless the repository content clearly explains it in user-facing terms. + + After the table, add one short paragraph with the primary selection rule. + + ## Target selection + + Start with one short introductory paragraph before the target subheadings. + The paragraph must be specific to this repository. + It should explain the selection principle, conceptual layering, or main trade-off across the targets. + Do not repeat the Overview table row by row. + Do not use generic phrases such as "the following packages are available". + + Then use one third-level heading per target. + + Format: + + ### Target.Name + + 1 short paragraph. + Explain what this target is for, what it adds, and when a developer should choose it. + If it extends another target in the same repository, say so. + If it is a convenience or meta package, say that clearly. + Do not create bullets unless the target has genuinely enumerable capabilities. + Use target names exactly as supplied. + + ## Usage guidance + + One or two paragraphs. + Explain the non-obvious guidance that helps developers choose and use the repository correctly. + Focus on boundaries, trade-offs, and common mistakes. + It must be grounded in the actual target responsibilities and APIs. + Do not use generic advice. + """; + } + + private static void AppendMultiline(StringBuilder sb, string value) + { + sb.AppendLine(value.Trim()); + sb.AppendLine(); + } + + private static async Task PackWithRepomixAsync(string cloneDir, string includes) + { + var outputFile = Path.Combine(Path.GetTempPath(), "repomix-story-" + Guid.NewGuid().ToString("N") + ".xml"); + try + { + var executable = ResolveNpxExecutable(); + await RunProcessAsync(executable, + ["--yes", "repomix", "--include", includes, "--style", "xml", "--output", outputFile, "--no-file-summary", "--quiet"], + cloneDir); + + if (!File.Exists(outputFile)) + { + throw new InvalidOperationException("repomix completed without creating the expected output file."); + } + + return await File.ReadAllTextAsync(outputFile, Encoding.UTF8); + } + finally + { + TryDeleteFile(outputFile); + } + } + + private static string ResolveNpxExecutable() + { + if (!OperatingSystem.IsWindows()) + { + return "npx"; + } + + var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); + if (!string.IsNullOrWhiteSpace(programFiles)) + { + var nodeNpx = Path.Combine(programFiles, "nodejs", "npx.cmd"); + if (File.Exists(nodeNpx)) + { + return nodeNpx; + } + } + + var programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); + if (!string.IsNullOrWhiteSpace(programFilesX86)) + { + var nodeNpx = Path.Combine(programFilesX86, "nodejs", "npx.cmd"); + if (File.Exists(nodeNpx)) + { + return nodeNpx; + } + } + + return "npx.cmd"; + } + + private static async Task WriteManifestAsync( + string manifestPath, + StoryOptions options, + string repoId, + string workspace, + IReadOnlyList targets, + string overviewContextName) + { + var packagesPhase = new + { + name = "packages", + targets = targets.Select(t => new { t.kind, t.name, t.context, t.result }).ToList() + }; + + var overviewPhase = new + { + name = "overview", + dependsOn = "packages", + target = new + { + kind = "overview", + name = "Index", + context = overviewContextName, + result = "result/Index.md" + } + }; + + var manifest = new + { + schemaVersion = 1, + generatedAt = DateTimeOffset.UtcNow.ToString("O"), + repository = new + { + url = options.RepoUrl, + id = repoId + }, + output = new + { + root = options.OutputRoot, + workspace, + resultDirectory = ResultDirectoryName + }, + phases = new object[] { packagesPhase, overviewPhase }, + targets, + overview = overviewPhase.target + }; + + var json = JsonSerializer.Serialize(manifest, new JsonSerializerOptions { WriteIndented = true }); + await WriteUtf8Async(manifestPath, json + Environment.NewLine); + } + + private static async Task RunProcessAsync(string executable, IReadOnlyList arguments, string workingDirectory) + { + var startInfo = new ProcessStartInfo(executable) + { + WorkingDirectory = workingDirectory, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + + foreach (var argument in arguments) + { + startInfo.ArgumentList.Add(argument); + } + + using var process = Process.Start(startInfo) + ?? throw new InvalidOperationException($"Could not start '{executable}'."); + + var stdoutTask = process.StandardOutput.ReadToEndAsync(); + var stderrTask = process.StandardError.ReadToEndAsync(); + + await process.WaitForExitAsync(); + var stdout = await stdoutTask; + var stderr = await stderrTask; + + if (process.ExitCode != 0) + { + var details = string.Join(Environment.NewLine, new[] { stdout.Trim(), stderr.Trim() }.Where(s => !string.IsNullOrWhiteSpace(s))); + throw new InvalidOperationException($"'{executable}' failed with exit code {process.ExitCode}.{Environment.NewLine}{details}".Trim()); + } + } + + private static void AppendHeader(StringBuilder sb, string value) + { + sb.AppendLine("## " + value); + sb.AppendLine(); + } + + private static async Task WriteUtf8Async(string path, string content) + { + Directory.CreateDirectory(Path.GetDirectoryName(path) ?? Directory.GetCurrentDirectory()); + await File.WriteAllTextAsync(path, content, new UTF8Encoding(false)); + } + + private static void TryDeleteFile(string path) + { + try + { + if (File.Exists(path)) + { + File.Delete(path); + } + } + catch + { + // Temp cleanup failure should not hide the real result. + } + } + + private static void TryDeleteDirectory(string path) + { + try + { + if (Directory.Exists(path)) + { + Directory.Delete(path, recursive: true); + } + } + catch + { + // Temp cleanup failure should not hide the real result. + } + } + + private static void PrintUsage() + { + Console.WriteLine( + """ + git-story-teller deterministic context generator + + Usage: + dotnet run --file scripts/story.cs -- --repo-url --output-root + + Required: + --repo-url Fully qualified git repository URL, for example https://github.com/owner/repo + --output-root Directory where the {repo-id} story workspace will be written + + Fixed conventions: + repo-id Derived from the final repository URL path segment + result dir result + + Output: + {output-root}/{repo-id}/manifest.json + {output-root}/{repo-id}/instructions.md + {output-root}/{repo-id}/*.context.md + {output-root}/{repo-id}/result/ + + Notes: + - This script writes deterministic context only. + - This script does not call an LLM. + - Existing result/*.md files are not overwritten. + """); + } +} + +internal sealed record StoryOptions(string RepoUrl, string OutputRoot); + +internal sealed record ProjectMetadata( + string PackageId, + string AssemblyName, + bool? IsPackable, + IReadOnlyList BundledPackages); + +internal sealed record TargetInfo( + string Name, + string SourcePath, + string? TestPath, + bool IsConveniencePackage, + IReadOnlyList BundledPackages); + +internal sealed record TargetManifestEntry( + string kind, + string name, + string context, + string result); \ No newline at end of file From b3f48fd7177b66cbbcc0b7f872d6ae620cbecfbd Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 15:53:44 +0200 Subject: [PATCH 03/14] =?UTF-8?q?=F0=9F=93=9D=20document=20git-story-telle?= =?UTF-8?q?r=20in=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add git-story-teller to the installation instructions table and usage guidance sections. Explain the bundled C# runner approach, repository-generic input contract, deterministic output structure, and grounding-first prose model. --- README.md | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 963bf71..a595128 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ npx skills add https://github.com/codebeltnet/agentic --skill git-nuget-readme npx skills add https://github.com/codebeltnet/agentic --skill git-visual-squash-summary npx skills add https://github.com/codebeltnet/agentic --skill skill-creator-agnostic npx skills add https://github.com/codebeltnet/agentic --skill markdown-illustrator +npx skills add https://github.com/codebeltnet/agentic --skill git-story-teller npx skills add https://github.com/codebeltnet/agentic --skill trunk-first-repo npx skills add https://github.com/codebeltnet/agentic --skill dotnet-strong-name-signing npx skills add https://github.com/codebeltnet/agentic --skill dotnet-new-app-slnx @@ -82,7 +83,8 @@ npx skills add https://github.com/codebeltnet/agentic --skill dotnet-new-lib-sln | [git-nuget-readme](skills/git-nuget-readme/SKILL.md) | Git-aware NuGet README companion for .NET repos that advertise a package from `src/`. Resolves the real packable project the README should sell, combines git history with actual package metadata, source capabilities, and relevant tests when feasible, preserves honest badge/docs/contributing sections, and writes a forthcoming, adoption-friendly `README.md` with repo-derived branding, clear value, install, framework-support, and quick-start guidance. | | [git-visual-squash-summary](skills/git-visual-squash-summary/SKILL.md) | Non-mutating grouped-summary companion to `git-visual-commits`. Turns the full current feature branch into a curated set of compact summary lines for PR or squash-and-merge contexts by default, preserving technical identifiers, merging overlap, dropping low-signal noise, highlighting distinct meaningful efforts, and avoiding changelog-style wording, unsupported claims, needless commit-range questions, or commit-selection UI for ordinary branch-level squash requests. | | [skill-creator-agnostic](skills/skill-creator-agnostic/SKILL.md) | Runner-agnostic overlay for Anthropic `skill-creator`. Adds repo and environment guardrails for skill authoring and benchmarking: temp-workspace isolation, `iteration-N/eval-name/{config}/run-N/` benchmark layout, valid `grading.json` summaries, generated `benchmark.json`, honest `MEASURED` vs `SIMULATED` labeling, and sync/README discipline for repo-managed skills. | -| [markdown-illustrator](skills/markdown-illustrator/SKILL.md) | Reads a markdown file and answers directly in chat with one document-wide Visual Brief plus one compiled prompt. Infers a compact visual strategy by default, keeps follow-up questions near zero, and only branches when the user explicitly asks for added specificity. | +| [markdown-illustrator](skills/markdown-illustrator/SKILL.md) | Reads a markdown file and answers directly in chat with one document-wide Visual Brief plus one compiled prompt. Infers a compact visual strategy by default, keeps follow-up questions near zero, and only branches when the user explicitly asks for added specificity. | +| [git-story-teller](skills/git-story-teller/SKILL.md) | Turns any full repository URL into a deterministic story workspace using the bundled .NET file-based runner `scripts/story.cs`. Requires explicit `--repo-url` and `--output-root`, derives `{repo-id}`, fixes `result/`, writes target contexts plus manifest instructions, then guides the agent to write target stories before `result/Index.md`. | | [dotnet-new-lib-slnx](skills/dotnet-new-lib-slnx/SKILL.md) | Scaffold a new .NET NuGet library solution following codebeltnet engineering conventions. Dynamic defaults for TFM/repository metadata, latest-stable NuGet package resolution, tuning projects plus a tooling-based benchmark runner, TFM-aware test environments, strong-name signing, NuGet packaging, DocFX documentation, CI/CD pipeline, and code quality tooling. | | [dotnet-new-app-slnx](skills/dotnet-new-app-slnx/SKILL.md) | Scaffold a new .NET standalone application solution following codebeltnet engineering conventions. Supports Console, Web, and Worker host families with Startup or Minimal hosting patterns; Web expands into Empty Web, Web API, MVC, or Web App / Razor, plus functional tests and a simplified CI pipeline. | | [trunk-first-repo](skills/trunk-first-repo/SKILL.md) | Initialize a git repository following [scaled trunk-based development](https://trunkbaseddevelopment.com/#scaled-trunk-based-development). Seeds an empty `main` branch and creates a versioned feature branch (`v0.1.0/init`), enforcing a PR-first workflow where content only reaches main through peer-reviewed pull requests. | @@ -128,10 +130,16 @@ npx skills add https://github.com/codebeltnet/agentic --skill git-visual-squash- npx skills add https://github.com/codebeltnet/agentic --skill skill-creator-agnostic ``` -`markdown-illustrator` - -```bash -npx skills add https://github.com/codebeltnet/agentic --skill markdown-illustrator +`markdown-illustrator` + +```bash +npx skills add https://github.com/codebeltnet/agentic --skill markdown-illustrator +``` + +`git-story-teller` + +```bash +npx skills add https://github.com/codebeltnet/agentic --skill git-story-teller ``` `dotnet-new-lib-slnx` @@ -273,6 +281,19 @@ Anthropic's `skill-creator` is an excellent base workflow, but the day-to-day fr - **Codex-friendly benchmarking** — treats Codex CLI as a valid real runner when present, preserves `MEASURED` parity honestly, uses raw event output as fallback evidence when convenience files are missing, and prefers parallel paired runs when the runner supports sub-agents - **Repo-managed discipline** — keeps per-skill evals, local-install sync, and README updates in scope for first-party skills +### Why git-story-teller? + +Repository story generation works best when deterministic context gathering is separated from AI-authored prose. **git-story-teller** owns that split: its bundled .NET file-based runner creates the manifest, instructions, and one context file per target; the agent writes the target stories and overview. + +- **Bundled C# runner** - ships `scripts/story.cs`, run with `dotnet run --file`, so the skill is self-contained without a full project file +- **Repository-generic input** - starts from a full repository URL and an explicit output root instead of assuming an owner/slug convention +- **KISS contract** - only `--repo-url` and `--output-root` are inputs; `{repo-id}` is derived and `result/` is fixed +- **Codebelt-flavored default** - recommends `.bot/stories` when the active workspace already contains a `.bot` folder +- **Tool output is authoritative** - reads `manifest.json`, `instructions.md`, and one target context at a time instead of reconstructing scope from memory +- **Target-first workflow** - writes `result/{TargetName}.md` files before synthesizing `result/Index.md` +- **Context-budget aware** - processes target contexts separately and uses completed target stories for the overview +- **Grounded prose** - forbids invented APIs, relationships, examples, and broad marketing claims unless the generated context supports them +- **Publication stays explicit** - leaves staged files in `{output-root}/{repo-id}/result` unless the user asks to sync them into a consuming site ### Why markdown-illustrator? Markdown-heavy documents often need one image that sells the whole idea fast: a conference opener, article cover, pitch-slide hero, or visual hook that makes the audience want to keep reading. The problem with many prompt workflows is that they branch immediately into model menus, theme toggles, and style comparisons before the document has even been understood. From 39e2af7a519d5c449136cf711809e33641b1e4c1 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 16:34:35 +0200 Subject: [PATCH 04/14] =?UTF-8?q?=F0=9F=93=9D=20add=20Karpathy=20rules=20t?= =?UTF-8?q?o=20agent=20guidelines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index fd6626d..412b412 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -282,3 +282,63 @@ Debug triggering: ask Claude `"When would you use the [skill name] skill?"` — | Instructions not followed | Too verbose or ambiguous | Shorten, use bullets, move detail to `references/` | | Slow / degraded responses | Too much content loaded | Keep SKILL.md under 5k words, use progressive disclosure | +## Karpathy Rules + +Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed. + +### 1. Think Before Coding + +**Don't assume. Don't hide confusion. Surface tradeoffs.** + +Before implementing: +- State your assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them - don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. +- When the root cause is uncertain, do not present hypotheses as facts. State the uncertainty explicitly and ask whether to investigate before applying a fix. + +### 2. Simplicity First + +**Minimum code that solves the problem. Nothing speculative.** + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios. +- If you write 200 lines and it could be 50, rewrite it. + +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +### 3. Surgical Changes + +**Touch only what you must. Clean up only your own mess.** + +When editing existing code: +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it - don't delete it. + +When your changes create orphans: +- Remove imports/variables/functions that YOUR changes made unused. +- Don't remove pre-existing dead code unless asked. + +The test: Every changed line should trace directly to the user's request. + +### 4. Goal-Driven Execution + +**Define success criteria. Loop until verified.** + +Transform tasks into verifiable goals: +- "Add validation" → "Write tests for invalid inputs, then make them pass" +- "Fix the bug" → "Write a test that reproduces it, then make it pass" +- "Refactor X" → "Ensure tests pass before and after" + +For multi-step tasks, state a brief plan: +``` +1. [Step] → verify: [check] +2. [Step] → verify: [check] +3. [Step] → verify: [check] +``` + +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification. From a1f4768c94032f7fca587e11636a6ee16d122008 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 16:34:39 +0200 Subject: [PATCH 05/14] =?UTF-8?q?=F0=9F=A6=BE=20implement=20Repomix=20web?= =?UTF-8?q?=20API=20and=20.NET=20packer=20fallbacks=20in=20git-story-telle?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/git-story-teller/agents/openai.yaml | 4 - skills/git-story-teller/scripts/story.cs | 218 ++++++++++++++++++++- 2 files changed, 215 insertions(+), 7 deletions(-) delete mode 100644 skills/git-story-teller/agents/openai.yaml diff --git a/skills/git-story-teller/agents/openai.yaml b/skills/git-story-teller/agents/openai.yaml deleted file mode 100644 index 096d425..0000000 --- a/skills/git-story-teller/agents/openai.yaml +++ /dev/null @@ -1,4 +0,0 @@ -interface: - display_name: "Git Story Teller" - short_description: "Write grounded repo stories from ContentSync bundles." - default_prompt: "Use git-story-teller to generate source-grounded target stories and an overview from a generic ContentSync story workspace." \ No newline at end of file diff --git a/skills/git-story-teller/scripts/story.cs b/skills/git-story-teller/scripts/story.cs index ca856dc..44a8a88 100644 --- a/skills/git-story-teller/scripts/story.cs +++ b/skills/git-story-teller/scripts/story.cs @@ -4,6 +4,7 @@ #:property PublishAot=false using System.Diagnostics; +using System.Net.Http; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; @@ -324,7 +325,7 @@ private static async Task BuildTargetContextAsync(string repoUrl, string } includeParts.Add(".nuget/**/README.md"); - var repomix = await PackWithRepomixAsync(cloneDir, string.Join(',', includeParts)); + var repomix = await PackRepositoryContentAsync(repoUrl, cloneDir, string.Join(',', includeParts)); var sb = new StringBuilder(); AppendHeader(sb, "TARGET IDENTITY"); @@ -360,7 +361,7 @@ private static async Task BuildTargetContextAsync(string repoUrl, string private static async Task BuildOverviewContextAsync(string repoUrl, string cloneDir, string repoId, IReadOnlyList targets) { Console.WriteLine("[story] packing overview context..."); - var repomix = await PackWithRepomixAsync(cloneDir, "README.md,.nuget/**/README.md,Directory.Build.props,Directory.Build.targets,Directory.Packages.props,src/**/*.csproj"); + var repomix = await PackRepositoryContentAsync(repoUrl, cloneDir, "README.md,.nuget/**/README.md,Directory.Build.props,Directory.Build.targets,Directory.Packages.props,src/**/*.csproj"); var sb = new StringBuilder(); AppendHeader(sb, "REPOSITORY IDENTITY"); @@ -668,6 +669,34 @@ private static void AppendMultiline(StringBuilder sb, string value) sb.AppendLine(); } + private static async Task PackRepositoryContentAsync(string repoUrl, string cloneDir, string includes) + { + try + { + return await PackWithRepomixAsync(cloneDir, includes); + } + catch (Exception ex) when (CanUseDotNetPackerFallback(ex)) + { + Console.WriteLine("[story] local repomix unavailable: " + ex.Message.Split(Environment.NewLine)[0]); + + if (CanUseRepomixWebApi(repoUrl)) + { + try + { + Console.WriteLine("[story] trying Repomix web API fallback."); + return await PackWithRepomixWebApiAsync(repoUrl, includes); + } + catch (Exception webEx) + { + Console.WriteLine("[story] Repomix web API fallback unavailable: " + webEx.Message.Split(Environment.NewLine)[0]); + } + } + + Console.WriteLine("[story] using built-in .NET context packer fallback."); + return await PackWithDotNetPackerAsync(cloneDir, includes); + } + } + private static async Task PackWithRepomixAsync(string cloneDir, string includes) { var outputFile = Path.Combine(Path.GetTempPath(), "repomix-story-" + Guid.NewGuid().ToString("N") + ".xml"); @@ -691,6 +720,186 @@ await RunProcessAsync(executable, } } + private static bool CanUseDotNetPackerFallback(Exception ex) + { + var message = ex.ToString(); + var fallbackSignals = new[] + { + "Could not start", + "error occurred trying to start process", + "The system cannot find the file specified", + "No such file or directory", + "could not determine executable to run", + "ENOTFOUND", + "EAI_AGAIN", + "ETIMEDOUT", + "ECONNRESET", + "ECONNREFUSED", + "registry.npmjs.org", + "npm ERR! code" + }; + + return fallbackSignals.Any(signal => message.Contains(signal, StringComparison.OrdinalIgnoreCase)); + } + + private static bool CanUseRepomixWebApi(string repoUrl) + { + return Uri.TryCreate(repoUrl, UriKind.Absolute, out var uri) + && uri.Scheme is "http" or "https" + && string.Equals(uri.Host, "github.com", StringComparison.OrdinalIgnoreCase); + } + + private static async Task PackWithRepomixWebApiAsync(string repoUrl, string includes) + { + using var http = new HttpClient(); + using var content = new MultipartFormDataContent + { + { new StringContent(repoUrl, Encoding.UTF8), "url" }, + { new StringContent("xml", Encoding.UTF8), "format" }, + { new StringContent(BuildRepomixWebOptions(includes), Encoding.UTF8), "options" } + }; + + using var response = await http.PostAsync("https://api.repomix.com/api/pack", content); + var body = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) + { + throw new InvalidOperationException($"Repomix web API returned HTTP {(int)response.StatusCode}."); + } + + foreach (var line in body.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) + { + using var json = JsonDocument.Parse(line); + var root = json.RootElement; + if (root.TryGetProperty("type", out var type) && string.Equals(type.GetString(), "result", StringComparison.OrdinalIgnoreCase)) + { + return root.GetProperty("data").GetProperty("content").GetString() + ?? throw new InvalidOperationException("Repomix web API returned an empty result."); + } + + if (root.TryGetProperty("type", out var errorType) && string.Equals(errorType.GetString(), "error", StringComparison.OrdinalIgnoreCase)) + { + var message = root.TryGetProperty("message", out var messageElement) + ? messageElement.GetString() + : "Repomix web API returned an error."; + throw new InvalidOperationException(message); + } + } + + throw new InvalidOperationException("Repomix web API did not return a result event."); + } + + private static string BuildRepomixWebOptions(string includes) + { + var options = new + { + removeComments = false, + removeEmptyLines = false, + showLineNumbers = false, + fileSummary = false, + directoryStructure = true, + includePatterns = includes, + outputParsable = false, + compress = false + }; + + return JsonSerializer.Serialize(options); + } + + private static async Task PackWithDotNetPackerAsync(string cloneDir, string includes) + { + var includePatterns = includes + .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .ToList(); + + var files = Directory.EnumerateFiles(cloneDir, "*", SearchOption.AllDirectories) + .Select(path => new PackedFile(path, Path.GetRelativePath(cloneDir, path).Replace('\\', '/'))) + .Where(file => ShouldIncludeFile(file.RelativePath, includePatterns)) + .Where(file => !IsUnderSkippedDirectory(file.RelativePath)) + .Where(file => IsTextFile(file.FullPath)) + .OrderBy(file => file.RelativePath, StringComparer.OrdinalIgnoreCase) + .ToList(); + + var filesElement = new XElement("files"); + foreach (var file in files) + { + var content = await File.ReadAllTextAsync(file.FullPath, Encoding.UTF8); + filesElement.Add(new XElement("file", new XAttribute("path", file.RelativePath), content)); + } + + var doc = new XDocument( + new XElement( + "repository-context", + new XAttribute("generatedBy", "git-story-teller-dotnet-fallback"), + new XElement("note", "Repomix was unavailable, so this fallback packed selected text files with a simple .NET reader. It does not provide Repomix token counts, Secretlint checks, or exact gitignore semantics."), + new XElement("includePatterns", includePatterns.Select(pattern => new XElement("pattern", pattern))), + new XElement("directoryStructure", BuildDirectoryStructure(files.Select(file => file.RelativePath))), + filesElement)); + + return doc.ToString(SaveOptions.DisableFormatting); + } + + private static bool ShouldIncludeFile(string relativePath, IReadOnlyList includePatterns) => + includePatterns.Any(pattern => MatchesIncludePattern(relativePath, pattern)); + + private static bool MatchesIncludePattern(string relativePath, string pattern) + { + var normalizedPattern = pattern.Replace('\\', '/').TrimStart('/'); + + if (normalizedPattern.EndsWith("/**", StringComparison.Ordinal)) + { + var prefix = normalizedPattern[..^3].TrimEnd('/'); + return string.Equals(relativePath, prefix, StringComparison.OrdinalIgnoreCase) + || relativePath.StartsWith(prefix + "/", StringComparison.OrdinalIgnoreCase); + } + + if (normalizedPattern.Contains("/**/", StringComparison.Ordinal)) + { + var parts = normalizedPattern.Split("/**/", 2, StringSplitOptions.None); + return relativePath.StartsWith(parts[0].TrimEnd('/') + "/", StringComparison.OrdinalIgnoreCase) + && relativePath.EndsWith("/" + parts[1].TrimStart('/'), StringComparison.OrdinalIgnoreCase); + } + + if (normalizedPattern.Contains('*')) + { + var regex = "^" + Regex.Escape(normalizedPattern) + .Replace("\\*\\*", ".*", StringComparison.Ordinal) + .Replace("\\*", "[^/]*", StringComparison.Ordinal) + "$"; + return Regex.IsMatch(relativePath, regex, RegexOptions.IgnoreCase); + } + + return string.Equals(relativePath, normalizedPattern, StringComparison.OrdinalIgnoreCase); + } + + private static bool IsUnderSkippedDirectory(string relativePath) + { + var segments = relativePath.Split('/', StringSplitOptions.RemoveEmptyEntries); + return segments.Any(segment => segment is ".git" or ".svn" or ".hg" or "bin" or "obj" or "node_modules"); + } + + private static bool IsTextFile(string path) + { + using var stream = File.OpenRead(path); + var buffer = new byte[Math.Min(4096, (int)Math.Min(stream.Length, int.MaxValue))]; + var read = stream.Read(buffer, 0, buffer.Length); + return !buffer.Take(read).Contains((byte)0); + } + + private static string BuildDirectoryStructure(IEnumerable relativePaths) + { + var entries = new SortedSet(StringComparer.OrdinalIgnoreCase); + foreach (var path in relativePaths) + { + var parts = path.Split('/', StringSplitOptions.RemoveEmptyEntries); + for (var i = 0; i < parts.Length; i++) + { + var prefix = string.Join('/', parts.Take(i + 1)); + entries.Add(prefix + (i == parts.Length - 1 ? string.Empty : "/")); + } + } + + return string.Join(Environment.NewLine, entries); + } + private static string ResolveNpxExecutable() { if (!OperatingSystem.IsWindows()) @@ -874,6 +1083,7 @@ result dir result - This script writes deterministic context only. - This script does not call an LLM. - Existing result/*.md files are not overwritten. + - Context packing prefers local Repomix, then the Repomix web API for GitHub HTTPS URLs, then the built-in .NET fallback. """); } } @@ -897,4 +1107,6 @@ internal sealed record TargetManifestEntry( string kind, string name, string context, - string result); \ No newline at end of file + string result); + +internal sealed record PackedFile(string FullPath, string RelativePath); From 04f96d03f0cbdfc24c71b3109ef6b1db982474bd Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 16:34:43 +0200 Subject: [PATCH 06/14] =?UTF-8?q?=F0=9F=92=AC=20update=20git-story-teller?= =?UTF-8?q?=20docs=20and=20evals=20for=20fallback-aware=20context=20packin?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- skills/git-story-teller/SKILL.md | 14 ++++- skills/git-story-teller/evals/evals.json | 76 +++++++++++++++++++++--- 3 files changed, 85 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a595128..a52e448 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ npx skills add https://github.com/codebeltnet/agentic --skill dotnet-new-lib-sln | [git-visual-squash-summary](skills/git-visual-squash-summary/SKILL.md) | Non-mutating grouped-summary companion to `git-visual-commits`. Turns the full current feature branch into a curated set of compact summary lines for PR or squash-and-merge contexts by default, preserving technical identifiers, merging overlap, dropping low-signal noise, highlighting distinct meaningful efforts, and avoiding changelog-style wording, unsupported claims, needless commit-range questions, or commit-selection UI for ordinary branch-level squash requests. | | [skill-creator-agnostic](skills/skill-creator-agnostic/SKILL.md) | Runner-agnostic overlay for Anthropic `skill-creator`. Adds repo and environment guardrails for skill authoring and benchmarking: temp-workspace isolation, `iteration-N/eval-name/{config}/run-N/` benchmark layout, valid `grading.json` summaries, generated `benchmark.json`, honest `MEASURED` vs `SIMULATED` labeling, and sync/README discipline for repo-managed skills. | | [markdown-illustrator](skills/markdown-illustrator/SKILL.md) | Reads a markdown file and answers directly in chat with one document-wide Visual Brief plus one compiled prompt. Infers a compact visual strategy by default, keeps follow-up questions near zero, and only branches when the user explicitly asks for added specificity. | -| [git-story-teller](skills/git-story-teller/SKILL.md) | Turns any full repository URL into a deterministic story workspace using the bundled .NET file-based runner `scripts/story.cs`. Requires explicit `--repo-url` and `--output-root`, derives `{repo-id}`, fixes `result/`, writes target contexts plus manifest instructions, then guides the agent to write target stories before `result/Index.md`. | +| [git-story-teller](skills/git-story-teller/SKILL.md) | Turns any full repository URL into a deterministic story workspace using the bundled .NET file-based runner `scripts/story.cs`. Requires explicit `--repo-url` and `--output-root`, derives `{repo-id}`, fixes `result/`, packs context with local Repomix when available, the public Repomix web API for GitHub URLs when Node/npm is unavailable, or a lower-fidelity built-in .NET fallback as the last resort, writes target contexts plus manifest instructions, then guides the agent to write target stories before `result/Index.md`. | | [dotnet-new-lib-slnx](skills/dotnet-new-lib-slnx/SKILL.md) | Scaffold a new .NET NuGet library solution following codebeltnet engineering conventions. Dynamic defaults for TFM/repository metadata, latest-stable NuGet package resolution, tuning projects plus a tooling-based benchmark runner, TFM-aware test environments, strong-name signing, NuGet packaging, DocFX documentation, CI/CD pipeline, and code quality tooling. | | [dotnet-new-app-slnx](skills/dotnet-new-app-slnx/SKILL.md) | Scaffold a new .NET standalone application solution following codebeltnet engineering conventions. Supports Console, Web, and Worker host families with Startup or Minimal hosting patterns; Web expands into Empty Web, Web API, MVC, or Web App / Razor, plus functional tests and a simplified CI pipeline. | | [trunk-first-repo](skills/trunk-first-repo/SKILL.md) | Initialize a git repository following [scaled trunk-based development](https://trunkbaseddevelopment.com/#scaled-trunk-based-development). Seeds an empty `main` branch and creates a versioned feature branch (`v0.1.0/init`), enforcing a PR-first workflow where content only reaches main through peer-reviewed pull requests. | @@ -286,6 +286,9 @@ Anthropic's `skill-creator` is an excellent base workflow, but the day-to-day fr Repository story generation works best when deterministic context gathering is separated from AI-authored prose. **git-story-teller** owns that split: its bundled .NET file-based runner creates the manifest, instructions, and one context file per target; the agent writes the target stories and overview. - **Bundled C# runner** - ships `scripts/story.cs`, run with `dotnet run --file`, so the skill is self-contained without a full project file +- **Repomix-first packing** - uses `npx repomix` for the canonical XML context, ignore handling, token metadata, and security checks when Node/npm access is available +- **Web API fallback** - if local Repomix cannot start and the input is a public GitHub HTTPS URL, posts the same pack request shape used by `https://repomix.com/` to the public Repomix API +- **Local fallback path** - if both Repomix paths are unavailable, uses a simple built-in .NET text packer so public/non-sensitive story work can still proceed - **Repository-generic input** - starts from a full repository URL and an explicit output root instead of assuming an owner/slug convention - **KISS contract** - only `--repo-url` and `--output-root` are inputs; `{repo-id}` is derived and `result/` is fixed - **Codebelt-flavored default** - recommends `.bot/stories` when the active workspace already contains a `.bot` folder diff --git a/skills/git-story-teller/SKILL.md b/skills/git-story-teller/SKILL.md index 668f2e5..7446981 100644 --- a/skills/git-story-teller/SKILL.md +++ b/skills/git-story-teller/SKILL.md @@ -52,7 +52,17 @@ repo-id Derived from the final repository URL path segment, with .git remov result dir result ``` -The runner requires the .NET 10 SDK or newer, `git`, and `npx`/repomix access. If these are unavailable, stop and report the missing dependency. +The runner requires the .NET 10 SDK or newer and `git`. It prefers Repomix through `npx repomix` for high-fidelity packing, because Repomix provides the canonical XML shape, ignore handling, token-aware metadata, and security checks. If `npx`/Repomix cannot start or npm registry access is unavailable, the runner tries the same public Repomix web API used by `https://repomix.com/` for GitHub HTTPS repository URLs. If both Repomix paths are unavailable, it falls back to its built-in .NET text packer so the workspace can still be generated. + +Fallback notes: + +- The Repomix web API fallback posts the repository URL, output format, and include patterns to `https://api.repomix.com/api/pack`; use it only for public GitHub repositories or repositories the user is comfortable sending to that service. +- The built-in .NET fallback is local-only and packs only files matching the runner's include patterns. +- The built-in .NET fallback does not provide Repomix token counts, Secretlint checks, compression, or exact gitignore semantics. +- If `.NET 10` or `git` is unavailable, stop and report the missing dependency. +- If Repomix runs and rejects content, do not bypass that result manually with a fallback unless the user explicitly accepts the lower-fidelity path. + +Do not scrape or drive the browser UI. If a web fallback is needed, call the Repomix API endpoint directly and keep the lower-fidelity .NET fallback available in case the public service changes or is unreachable. ## Expected Workspace @@ -202,4 +212,4 @@ Do not copy staged results there unless the user asks for website sync, publicat - Loading the entire repository context for every target story. - Writing `Index.md` before target stories exist. - Inventing usage examples from plausible framework patterns rather than supplied source and tests. -- Copying staged files into website content without an explicit user request. \ No newline at end of file +- Copying staged files into website content without an explicit user request. diff --git a/skills/git-story-teller/evals/evals.json b/skills/git-story-teller/evals/evals.json index cfbba39..d484e51 100644 --- a/skills/git-story-teller/evals/evals.json +++ b/skills/git-story-teller/evals/evals.json @@ -2,14 +2,76 @@ "skill_name": "git-story-teller", "evals": [ { - "id": "eval-target-first-story-workspace", - "prompt": "Use git-story-teller to complete stories for an existing generated workspace at .bot/stories/example-project. The workspace has manifest.json, instructions.md, target context files, overview.context.md, and an empty result folder.", - "expected_output": "Inspects manifest.json and instructions.md first, writes target result files under result/{TargetName}.md before result/Index.md, processes one target context at a time, treats generated output as source of truth, follows PACKAGE STORY PROMPT and OVERVIEW STORY PROMPT sections, and reports validation gaps without copying files into a website content tree unless explicitly asked." + "id": 1, + "prompt": "Use git-story-teller to write target stories and the overview for an existing story workspace at .bot/stories/example-project. The workspace has manifest.json, instructions.md, two target context files, overview.context.md, and an empty result folder.", + "expected_output": "Reads manifest.json and instructions.md first, writes result/{TargetName}.md files before result/Index.md, processes one target context at a time, treats generated output as source of truth, and reports validation gaps without copying files to a website content tree unless explicitly asked.", + "expectations": [ + "Reads manifest.json and instructions.md before writing any result file", + "Writes result/{TargetName}.md files before result/Index.md", + "Processes one target context file at a time instead of loading all contexts together", + "Treats the generated manifest as authoritative for target names, context paths, result paths, and phase order", + "Does not invent APIs, namespaces, or capabilities not present in the target context", + "Stops after reporting validation gaps rather than copying result files to a website content tree" + ] }, { - "id": "eval-generate-deterministic-context-full-url", - "prompt": "Use git-story-teller to generate story context for https://github.com/example/project and then write the target stories and overview. The current workspace contains a .bot folder.", - "expected_output": "Recommends .bot/stories as the required output root, runs or proposes dotnet run --file /scripts/story.cs with --repo-url and --output-root, avoids provider/model/reasoning LLM options, refuses slug-only hardcoded organization assumptions, does not ask for repo-id or result-dir, then follows the generated manifest and prompt sections to write result/Index.md and result/{TargetName}.md files." + "id": 2, + "prompt": "Use git-story-teller to generate a story workspace for https://github.com/example/myproject and then write the resulting stories. The active workspace contains a .bot folder.", + "expected_output": "Recommends .bot/stories as the output root, runs dotnet run --file with --repo-url and the full URL and --output-root, does not ask for repo-id or result directory, avoids LLM options, then follows the generated manifest to write target stories before result/Index.md.", + "expectations": [ + "Recommends .bot/stories as the output root because a .bot folder exists in the workspace", + "Runs dotnet run --file /scripts/story.cs with --repo-url and --output-root", + "Passes the full repository URL, not a slug or partial reference", + "Does not ask the user for repo-id or result directory", + "Does not pass provider, model, or LLM flags to the runner", + "Follows the generated manifest after the runner completes to write target stories before Index.md" + ] + }, + { + "id": 3, + "prompt": "Use git-story-teller to write result/Index.md from an existing story workspace. The context files and manifest are present but the result folder is empty.", + "expected_output": "Writes all required target result files before writing result/Index.md, using completed target stories as editorial input for the overview.", + "expectations": [ + "Writes all required target result files before writing result/Index.md", + "Does not skip target stories even when the user asks only for the overview", + "Uses the completed target result files as editorial input when writing Index.md", + "Names any missing target stories in the response if any cannot be completed before proceeding" + ] + }, + { + "id": 4, + "prompt": "Use git-story-teller to write a target story for a library package. The context file includes source files but contains no performance benchmarks, third-party integration examples, or architecture diagrams.", + "expected_output": "The result file contains only claims grounded in the context; no invented benchmarks, integration examples, broad marketing adjectives, or API shapes that do not appear in the source.", + "expectations": [ + "Grounds every capability claim in source, tests, project metadata, or README content from the context", + "Does not invent API shapes, method signatures, or namespaces not visible in the context", + "Omits benchmark or performance claims when no benchmark data is present in the context", + "Avoids broad adjectives such as robust, seamless, powerful, or comprehensive unless immediately backed by concrete evidence from the context", + "Uses the rg validation commands from the skill to check result files before reporting completion" + ] + }, + { + "id": 5, + "prompt": "Use git-story-teller to generate a story workspace but the runner exits with an error stating that the .NET 10 SDK is not installed.", + "expected_output": "Stops and reports the missing .NET dependency clearly instead of continuing with partial output or guessing story content.", + "expectations": [ + "Identifies .NET 10 SDK and git as required runner dependencies", + "Stops and reports the blocking dependency issue instead of proceeding with partial output", + "Does not attempt to generate story content by guessing when the runner cannot complete", + "Tells the user what to install to unblock the workflow" + ] + }, + { + "id": 6, + "prompt": "Use git-story-teller to generate a story workspace for https://github.com/example/myproject, but local npx/Repomix cannot start while .NET 10 and git are available.", + "expected_output": "Allows the runner to use the Repomix web API fallback for the public GitHub URL, or the built-in .NET packer if the web API is unavailable, then follows the generated manifest instead of treating missing npx as a hard blocker.", + "expectations": [ + "Does not stop solely because local npx or local Repomix is unavailable", + "Recognizes that the runner prefers local Repomix, then can try the public Repomix web API for GitHub HTTPS URLs", + "Mentions that the web API fallback sends the repository URL and include patterns to the public Repomix service", + "Recognizes the built-in .NET text packer as the last-resort lower-fidelity fallback", + "Still treats .NET 10 SDK and git failures as blocking dependencies" + ] } ] -} \ No newline at end of file +} From 3a055140575f8810af44b8328bf1314be65efe19 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 17:10:53 +0200 Subject: [PATCH 07/14] =?UTF-8?q?=F0=9F=92=AC=20finalize=20v0.4.0=20releas?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1ddb0e..d4d7198 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +## [0.4.0] - 2026-05-03 + +This is a minor release focused on deterministic repository story generation and foundational agent guidelines. It introduces a new `git-story-teller` skill with a bundled .NET context extractor, enhanced bot workspace management, and Karpathy programming principles for LLM agents. + +### Added + +- `git-story-teller` skill that reads a repository URL and generates a deterministic story overview and per-package target stories from grounded evidence, +- Bundled C# context packer (`scripts/story.cs`) that clones repositories, discovers package targets, extracts grounded evidence via Repomix, and stages deterministic fixtures for story generation, +- Karpathy rules in `AGENTS.md` for LLM-driven coding: think before implementing, favor simplicity, make surgical changes, and execute goal-driven with clear verification criteria, +- `.bot/` workspace pattern to `.gitignore` for local agentic workspaces and ephemeral state. + +### Changed + +- Updated README to document `git-story-teller` installation, usage, and bundled C# runner approach, +- Implemented Repomix web API and .NET packer fallbacks in `git-story-teller` for robust context extraction when network or CLI tools are unavailable. + ## [0.3.4] - 2026-04-24 This is a patch release that hardens the .NET scaffold guidance around hidden asset recovery and makes `git-keep-a-changelog` safer in yolo/auto mode. Incomplete `npx skills add` installs now pivot immediately to an upstream restore path driven by the shared asset manifest, while the changelog skill treats yolo/auto as an explicit full-autonomy mode instead of asking for scope confirmation. @@ -141,7 +157,8 @@ This is a minor release that introduces two complementary git workflow skills, e - Improved scaffold fidelity with hidden `.bot` asset preservation, explicit UTF-8 and BOM handling, and checks aimed at preventing mojibake or incomplete generated output. -[Unreleased]: https://github.com/codebeltnet/agentic/compare/v0.3.4...HEAD +[Unreleased]: https://github.com/codebeltnet/agentic/compare/v0.4.0...HEAD +[0.4.0]: https://github.com/codebeltnet/agentic/compare/v0.3.4...v0.4.0 [0.3.4]: https://github.com/codebeltnet/agentic/compare/v0.3.3...v0.3.4 [0.3.3]: https://github.com/codebeltnet/agentic/compare/v0.3.2...v0.3.3 [0.3.2]: https://github.com/codebeltnet/agentic/compare/v0.3.1...v0.3.2 From fdad2afb0a03a6a185f2e5e4d64b832174678699 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 17:10:57 +0200 Subject: [PATCH 08/14] =?UTF-8?q?=F0=9F=8D=B1=20add=20hero=20image=20to=20?= =?UTF-8?q?git-story-teller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/git-story-teller/SKILL.md | 2 ++ skills/git-story-teller/assets/hero.jpg | Bin 0 -> 136787 bytes 2 files changed, 2 insertions(+) create mode 100644 skills/git-story-teller/assets/hero.jpg diff --git a/skills/git-story-teller/SKILL.md b/skills/git-story-teller/SKILL.md index 7446981..611f365 100644 --- a/skills/git-story-teller/SKILL.md +++ b/skills/git-story-teller/SKILL.md @@ -6,6 +6,8 @@ description: > # Git Story Teller +![Git Story Teller](assets/hero.jpg) + Use this skill to turn a deterministic story workspace into website-ready or docs-ready Markdown. The bundled `scripts/story.cs` runner owns repository access, evidence gathering, target discovery, context packing, and generated instructions. The agent owns reading that evidence, writing the story files, and validating that every claim is grounded. ## Critical diff --git a/skills/git-story-teller/assets/hero.jpg b/skills/git-story-teller/assets/hero.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ff36d3f2e849e415e308b60b475a426be55dbe45 GIT binary patch literal 136787 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
q~eaZI*8FdoRa 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

v|$_`b=YwA$6_B8!y!4IVd)MRYP7 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%0AWZ>fE&L6gCnU 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 Date: Sun, 3 May 2026 17:24:27 +0200 Subject: [PATCH 09/14] =?UTF-8?q?=F0=9F=93=9D=20refine=20terminology=20in?= =?UTF-8?q?=20story=20template=20from=20target=20to=20package?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/git-story-teller/scripts/story.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/skills/git-story-teller/scripts/story.cs b/skills/git-story-teller/scripts/story.cs index 44a8a88..7d1fb68 100644 --- a/skills/git-story-teller/scripts/story.cs +++ b/skills/git-story-teller/scripts/story.cs @@ -611,23 +611,23 @@ Write exactly these three sections. ## Overview - Start with 2-3 sentences that explain the unifying purpose across the targets. + Start with 2-3 sentences that explain the unifying purpose across the packages. Make clear what kind of developer problem this repository solves. Do not use broad marketing language. - After the opening sentences, include a compact target selection table. + After the opening sentences, include a compact packages selection table. Columns: - | Scenario | Target | + | Scenario | Package | |---|---| Rules: - - Each row must map a concrete developer scenario to one or more target names. + - Each row must map a concrete developer scenario to one or more package names. - Keep the scenarios practical and non-overlapping. - Prefer fewer, sharper rows over exhaustive rows. - Do not create separate rows for scenarios that are effectively the same decision. - - Include convenience or aggregate targets only if they exist and their role is clear. + - Include convenience or aggregate packages only if they exist and their role is clear. - Avoid internal phrasing unless the repository content clearly explains it in user-facing terms. After the table, add one short paragraph with the primary selection rule. @@ -640,25 +640,25 @@ The paragraph must be specific to this repository. Do not repeat the Overview table row by row. Do not use generic phrases such as "the following packages are available". - Then use one third-level heading per target. + Then use one third-level heading per package. Format: - ### Target.Name + ### Package.Name 1 short paragraph. - Explain what this target is for, what it adds, and when a developer should choose it. - If it extends another target in the same repository, say so. + Explain what this package is for, what it adds, and when a developer should choose it. + If it extends another package in the same repository, say so. If it is a convenience or meta package, say that clearly. - Do not create bullets unless the target has genuinely enumerable capabilities. - Use target names exactly as supplied. + Do not create bullets unless the package has genuinely enumerable capabilities. + Use package names exactly as supplied. ## Usage guidance One or two paragraphs. Explain the non-obvious guidance that helps developers choose and use the repository correctly. Focus on boundaries, trade-offs, and common mistakes. - It must be grounded in the actual target responsibilities and APIs. + It must be grounded in the actual package responsibilities and APIs. Do not use generic advice. """; } From e454a3da0fbd46c1ac0c0be254a89798407dcb57 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 17:38:11 +0200 Subject: [PATCH 10/14] =?UTF-8?q?=F0=9F=93=9D=20update=20git-story-teller?= =?UTF-8?q?=20skill=20with=20package=20selection=20section=20and=20eval=20?= =?UTF-8?q?expectations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/git-story-teller/SKILL.md | 4 ++-- skills/git-story-teller/evals/evals.json | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/skills/git-story-teller/SKILL.md b/skills/git-story-teller/SKILL.md index 611f365..7b934ed 100644 --- a/skills/git-story-teller/SKILL.md +++ b/skills/git-story-teller/SKILL.md @@ -151,7 +151,7 @@ Do not use another target's context to fill gaps unless the current context expl Write `result/Index.md` only after target stories exist. -Use the overview context and the completed target result files as the main editorial input. The overview should help readers choose between targets or understand the repository's shape. It should not repeat every target page or amplify unsupported claims. +Use the overview context and the completed target result files as the main editorial input. The overview should help readers choose between packages or understand the repository's shape. It should not repeat every target page or amplify unsupported claims. If any target story is missing, decide from the manifest: @@ -200,7 +200,7 @@ Do not copy staged results there unless the user asks for website sync, publicat ## Good Output Characteristics - Target pages are concrete, source-backed, and useful to experienced developers. -- The overview explains target selection, repository boundaries, and relationships. +- The overview includes a `## Package selection` section that explains package selection, repository boundaries, and relationships. - The writing is restrained and developer-facing, not marketing-heavy. - The agent follows the generated manifest instead of improvising the run order. - The final response names the result files written and any validation gaps. diff --git a/skills/git-story-teller/evals/evals.json b/skills/git-story-teller/evals/evals.json index d484e51..29c02e6 100644 --- a/skills/git-story-teller/evals/evals.json +++ b/skills/git-story-teller/evals/evals.json @@ -4,13 +4,14 @@ { "id": 1, "prompt": "Use git-story-teller to write target stories and the overview for an existing story workspace at .bot/stories/example-project. The workspace has manifest.json, instructions.md, two target context files, overview.context.md, and an empty result folder.", - "expected_output": "Reads manifest.json and instructions.md first, writes result/{TargetName}.md files before result/Index.md, processes one target context at a time, treats generated output as source of truth, and reports validation gaps without copying files to a website content tree unless explicitly asked.", + "expected_output": "Reads manifest.json and instructions.md first, writes result/{TargetName}.md files before result/Index.md, processes one target context at a time, treats generated output as source of truth, writes the overview with a Package selection section, and reports validation gaps without copying files to a website content tree unless explicitly asked.", "expectations": [ "Reads manifest.json and instructions.md before writing any result file", "Writes result/{TargetName}.md files before result/Index.md", "Processes one target context file at a time instead of loading all contexts together", "Treats the generated manifest as authoritative for target names, context paths, result paths, and phase order", "Does not invent APIs, namespaces, or capabilities not present in the target context", + "Writes result/Index.md with a ## Package selection section and does not use the previous target-oriented heading", "Stops after reporting validation gaps rather than copying result files to a website content tree" ] }, @@ -30,11 +31,12 @@ { "id": 3, "prompt": "Use git-story-teller to write result/Index.md from an existing story workspace. The context files and manifest are present but the result folder is empty.", - "expected_output": "Writes all required target result files before writing result/Index.md, using completed target stories as editorial input for the overview.", + "expected_output": "Writes all required target result files before writing result/Index.md, using completed target stories as editorial input for the overview and using Package selection as the visible overview section heading.", "expectations": [ "Writes all required target result files before writing result/Index.md", "Does not skip target stories even when the user asks only for the overview", "Uses the completed target result files as editorial input when writing Index.md", + "Writes result/Index.md with a ## Package selection section and does not use the previous target-oriented heading", "Names any missing target stories in the response if any cannot be completed before proceeding" ] }, From dad58e95c2aedfab546dc34b497d6f3123398aac Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 17:38:13 +0200 Subject: [PATCH 11/14] =?UTF-8?q?=F0=9F=92=AC=20update=20README=20with=20g?= =?UTF-8?q?it-story-teller=20package=20selection=20section=20requirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a52e448..22e6013 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ npx skills add https://github.com/codebeltnet/agentic --skill dotnet-new-lib-sln | [git-visual-squash-summary](skills/git-visual-squash-summary/SKILL.md) | Non-mutating grouped-summary companion to `git-visual-commits`. Turns the full current feature branch into a curated set of compact summary lines for PR or squash-and-merge contexts by default, preserving technical identifiers, merging overlap, dropping low-signal noise, highlighting distinct meaningful efforts, and avoiding changelog-style wording, unsupported claims, needless commit-range questions, or commit-selection UI for ordinary branch-level squash requests. | | [skill-creator-agnostic](skills/skill-creator-agnostic/SKILL.md) | Runner-agnostic overlay for Anthropic `skill-creator`. Adds repo and environment guardrails for skill authoring and benchmarking: temp-workspace isolation, `iteration-N/eval-name/{config}/run-N/` benchmark layout, valid `grading.json` summaries, generated `benchmark.json`, honest `MEASURED` vs `SIMULATED` labeling, and sync/README discipline for repo-managed skills. | | [markdown-illustrator](skills/markdown-illustrator/SKILL.md) | Reads a markdown file and answers directly in chat with one document-wide Visual Brief plus one compiled prompt. Infers a compact visual strategy by default, keeps follow-up questions near zero, and only branches when the user explicitly asks for added specificity. | -| [git-story-teller](skills/git-story-teller/SKILL.md) | Turns any full repository URL into a deterministic story workspace using the bundled .NET file-based runner `scripts/story.cs`. Requires explicit `--repo-url` and `--output-root`, derives `{repo-id}`, fixes `result/`, packs context with local Repomix when available, the public Repomix web API for GitHub URLs when Node/npm is unavailable, or a lower-fidelity built-in .NET fallback as the last resort, writes target contexts plus manifest instructions, then guides the agent to write target stories before `result/Index.md`. | +| [git-story-teller](skills/git-story-teller/SKILL.md) | Turns any full repository URL into a deterministic story workspace using the bundled .NET file-based runner `scripts/story.cs`. Requires explicit `--repo-url` and `--output-root`, derives `{repo-id}`, fixes `result/`, packs context with local Repomix when available, the public Repomix web API for GitHub URLs when Node/npm is unavailable, or a lower-fidelity built-in .NET fallback as the last resort, writes target contexts plus manifest instructions, then guides the agent to write target stories before `result/Index.md` with a package-facing `## Package selection` overview section. | | [dotnet-new-lib-slnx](skills/dotnet-new-lib-slnx/SKILL.md) | Scaffold a new .NET NuGet library solution following codebeltnet engineering conventions. Dynamic defaults for TFM/repository metadata, latest-stable NuGet package resolution, tuning projects plus a tooling-based benchmark runner, TFM-aware test environments, strong-name signing, NuGet packaging, DocFX documentation, CI/CD pipeline, and code quality tooling. | | [dotnet-new-app-slnx](skills/dotnet-new-app-slnx/SKILL.md) | Scaffold a new .NET standalone application solution following codebeltnet engineering conventions. Supports Console, Web, and Worker host families with Startup or Minimal hosting patterns; Web expands into Empty Web, Web API, MVC, or Web App / Razor, plus functional tests and a simplified CI pipeline. | | [trunk-first-repo](skills/trunk-first-repo/SKILL.md) | Initialize a git repository following [scaled trunk-based development](https://trunkbaseddevelopment.com/#scaled-trunk-based-development). Seeds an empty `main` branch and creates a versioned feature branch (`v0.1.0/init`), enforcing a PR-first workflow where content only reaches main through peer-reviewed pull requests. | @@ -294,6 +294,7 @@ Repository story generation works best when deterministic context gathering is s - **Codebelt-flavored default** - recommends `.bot/stories` when the active workspace already contains a `.bot` folder - **Tool output is authoritative** - reads `manifest.json`, `instructions.md`, and one target context at a time instead of reconstructing scope from memory - **Target-first workflow** - writes `result/{TargetName}.md` files before synthesizing `result/Index.md` +- **Package-facing overview** - requires `result/Index.md` to use `## Package selection` for the reader-facing selection section - **Context-budget aware** - processes target contexts separately and uses completed target stories for the overview - **Grounded prose** - forbids invented APIs, relationships, examples, and broad marketing claims unless the generated context supports them - **Publication stays explicit** - leaves staged files in `{output-root}/{repo-id}/result` unless the user asks to sync them into a consuming site From b318c715f94e744edbea18e1aa14ef740489d7bd Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 17:41:52 +0200 Subject: [PATCH 12/14] =?UTF-8?q?=F0=9F=93=9D=20update=20overview=20story?= =?UTF-8?q?=20prompt=20to=20use=20package=20terminology=20consistently?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/git-story-teller/scripts/story.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/skills/git-story-teller/scripts/story.cs b/skills/git-story-teller/scripts/story.cs index 7d1fb68..df5f34c 100644 --- a/skills/git-story-teller/scripts/story.cs +++ b/skills/git-story-teller/scripts/story.cs @@ -572,7 +572,7 @@ Do not oversell it. private static string BuildOverviewStoryPrompt(string repoId, IReadOnlyList targets) { var targetList = targets.Count == 0 - ? "- No package targets discovered." + ? "- No packages discovered." : string.Join(Environment.NewLine, targets.Select(t => "- " + t.Name)); return $$""" @@ -586,7 +586,7 @@ private static string BuildOverviewStoryPrompt(string repoId, IReadOnlyList Date: Sun, 3 May 2026 17:50:58 +0200 Subject: [PATCH 13/14] =?UTF-8?q?=F0=9F=99=88=20add=20trailing=20newline?= =?UTF-8?q?=20to=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7ad005c..a86de9c 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,4 @@ skills/*-workspace/ **/grades.json # Bot workspace (local-only AI agent ideation, PRDs, and agentic loop state) -.bot/* \ No newline at end of file +.bot/* From 11ad0aa3b23810b1bfcf6ea0f8ab7f6b3f4b46bf Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sun, 3 May 2026 17:51:02 +0200 Subject: [PATCH 14/14] =?UTF-8?q?=F0=9F=90=9B=20resolve=20code=20review=20?= =?UTF-8?q?issues=20in=20git-story-teller/scripts/story.cs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix glob pattern matching for zero-depth paths (/**/suffix now matches prefix/suffix) - Add configurable timeout and cancellation token to RunProcessAsync (default 5 min) --- skills/git-story-teller/scripts/story.cs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/skills/git-story-teller/scripts/story.cs b/skills/git-story-teller/scripts/story.cs index df5f34c..100f38f 100644 --- a/skills/git-story-teller/scripts/story.cs +++ b/skills/git-story-teller/scripts/story.cs @@ -855,8 +855,12 @@ private static bool MatchesIncludePattern(string relativePath, string pattern) if (normalizedPattern.Contains("/**/", StringComparison.Ordinal)) { var parts = normalizedPattern.Split("/**/", 2, StringSplitOptions.None); - return relativePath.StartsWith(parts[0].TrimEnd('/') + "/", StringComparison.OrdinalIgnoreCase) - && relativePath.EndsWith("/" + parts[1].TrimStart('/'), StringComparison.OrdinalIgnoreCase); + var prefix = parts[0].TrimEnd('/') + "/"; + var suffix = "/" + parts[1].TrimStart('/'); + var direct = parts[0].TrimEnd('/') + "/" + parts[1].TrimStart('/'); + return (relativePath.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) + && relativePath.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) + || string.Equals(relativePath, direct, StringComparison.OrdinalIgnoreCase); } if (normalizedPattern.Contains('*')) @@ -981,8 +985,10 @@ private static async Task WriteManifestAsync( await WriteUtf8Async(manifestPath, json + Environment.NewLine); } - private static async Task RunProcessAsync(string executable, IReadOnlyList arguments, string workingDirectory) + private static async Task RunProcessAsync(string executable, IReadOnlyList arguments, string workingDirectory, TimeSpan timeout = default) { + if (timeout == default) timeout = TimeSpan.FromMinutes(5); + var startInfo = new ProcessStartInfo(executable) { WorkingDirectory = workingDirectory, @@ -1003,7 +1009,17 @@ private static async Task RunProcessAsync(string executable, IReadOnlyList