Skip to content

Ship public library packages alongside CLI for both C# and Rust#93

Merged
konard merged 6 commits into
mainfrom
issue-92-ce7d2849a3ea
May 15, 2026
Merged

Ship public library packages alongside CLI for both C# and Rust#93
konard merged 6 commits into
mainfrom
issue-92-ce7d2849a3ea

Conversation

@konard
Copy link
Copy Markdown
Member

@konard konard commented May 15, 2026

Summary

Closes #92.

Issue #92 asked us to double-check that both the C# and Rust
distributions publish a CLI and a public library, and to auto-generate
API documentation for each library so external projects can recreate or
extend the CLI without re-implementing the internals.

Root cause (C# only)

The Rust crate already ships a [lib] + [[bin]] pair, so cargo install link-cli and cargo add link-cli both work and docs.rs already renders
rustdoc. The defect was on the C# side: a single
Foundation.Data.Doublets.Cli csproj was declared as a dotnet tool with
<PackAsTool>true</PackAsTool>. .NET tools cannot be consumed via
<PackageReference> (they live under tools/<tfm>/any/, not
lib/<tfm>/), so the library surface — parser, query processors,
ChangesSimplifier, NamedTypesDecorator, PinnedTypesDecorator,
PersistentTransformationDecorator, LiNo I/O, UnicodeStringStorage
was inaccessible to downstream .NET code.

What ships in this PR

  1. C# project split. csharp/Foundation.Data.Doublets.Cli.Library/
    becomes a regular library project producing
    Foundation.Data.Doublets.Cli.dll and the
    Foundation.Data.Doublets.Cli
    NuGet. csharp/Foundation.Data.Doublets.Cli/ keeps <PackAsTool>true</PackAsTool>,
    contains only Program.cs plus System.CommandLine wiring, and continues
    to publish the clink dotnet
    tool — now via a <ProjectReference> on the library so they share a
    version. <GenerateDocumentationFile>true</GenerateDocumentationFile>
    embeds XML docs in the library .nupkg.

  2. NuGet release pipeline updated. .github/workflows/csharp.yml
    discovers both PackageIds and waits for both to appear on NuGet
    after publish. csharp/scripts/create-github-release.mjs now accepts
    multiple --package-id flags and renders shields.io badges + downloads
    counters for each one in the GitHub Release body. Two new unit tests in
    csharp/scripts/release-scripts.test.mjs cover the multi-package badge
    logic (22 → 24 tests).

  3. Rust crate metadata. rust/Cargo.toml gains documentation,
    homepage, categories, keywords, and a richer description so
    crates.io and docs.rs surface the library surface alongside the CLI.

  4. Auto-generated API documentation.

    • csharp/docfx.json, csharp/docs/index.md, and csharp/docs/toc.yml
      drive DocFX from the library's XML doc comments.
    • .github/workflows/docs.yml is a single unified workflow that builds
      DocFX (/csharp/) + cargo doc --no-deps --all-features (/rust/)
      into one _site/ and deploys it through actions/deploy-pages@v5
      (GitHub Pages only supports one deployment per repo, so combining
      is necessary).
    • Landing page at _site/index.html links into both sub-sites.
  5. READMEs. Root, csharp/, and rust/ READMEs all document the dual
    tool + library install paths side by side, link to docs.rs and the new
    GitHub Pages site, and add a second NuGet badge for the library.

  6. Changeset / changelog fragment.
    csharp/.changeset/issue-92-library-package.md and
    rust/changelog.d/20260515_140000_issue_92_library_metadata.md
    document the changes for the existing release pipelines so the next
    release picks them up.

  7. Case study. docs/case-studies/issue-92/ captures the original
    issue body, fetched comments, PR snapshot, file-trees of all four
    *-ai-driven-development-pipeline-template repos, snapshots of the
    relevant csproj / Cargo.toml / docfx.json / release.yml from those
    templates, and the full requirements → solution → verification trace.

Template defects observed (R7)

While comparing against the four templates, no functional defects were
found, but neither the C# template nor the Rust template demonstrates the
joint library + CLI case. The csharp template ships only a library;
the rust template ships only a library (no [[bin]]). That non-coverage
is plausibly what nudged the link-cli C# project into the tool-only
configuration that this PR corrects. The case study suggests filing a
follow-up in
link-foundation/csharp-ai-driven-development-pipeline-template
once this PR ships so other downstream projects don't repeat the mistake.

Test plan

  • dotnet build csharp/Foundation.Data.Doublets.Cli.sln --configuration Release
  • dotnet test csharp/Foundation.Data.Doublets.Cli.sln --configuration Release
  • dotnet pack csharp/Foundation.Data.Doublets.Cli.Library/Foundation.Data.Doublets.Cli.Library.csproj produces Foundation.Data.Doublets.Cli.<v>.nupkg containing lib/net8.0/Foundation.Data.Doublets.Cli.dll and Foundation.Data.Doublets.Cli.xml
  • dotnet pack csharp/Foundation.Data.Doublets.Cli/Foundation.Data.Doublets.Cli.csproj produces clink.<v>.nupkg with tools/net8.0/any/ content
  • cargo build --manifest-path rust/Cargo.toml --release
  • cargo test --manifest-path rust/Cargo.toml --all-features
  • cargo doc --manifest-path rust/Cargo.toml --no-deps --all-features produces rust/target/doc/link_cli/index.html
  • docfx csharp/docfx.json -o csharp/_site builds with 0 warnings, 0 errors and emits 30 HTML files
  • node csharp/scripts/release-scripts.test.mjs — 24/24 passing
  • Unified docs workflow ran successfully on 1b4a74e
    (run #25922536178)
  • All CI checks green on the final commit fc40263
    (C# / Rust / Docs / WebAssembly pipelines all SUCCESS)

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: #92
@konard konard self-assigned this May 15, 2026
konard added 4 commits May 15, 2026 14:04
The single `Foundation.Data.Doublets.Cli` csproj used `PackAsTool=true`
plus `OutputType=Exe`, which produces a .NET tool package that cannot
be consumed via `PackageReference`. External projects therefore had no
supported way to import the parser, query processors, decorators,
named/pinned types, persistent transformation triggers, or LiNo I/O
that the `clink` CLI is built on top of.

Split the C# project so the same source code now ships as two NuGet
packages: a reusable library (`Foundation.Data.Doublets.Cli`, with XML
doc generation enabled) and a thin CLI tool (`clink`, `PackAsTool=true`,
references the library). The release workflow resolves both package
ids, waits for both on the flat-container endpoint, and the GitHub
release body now embeds version + downloads shields.io badges for both
packages.

The Rust crate already ships both `[lib]` and `[[bin]]` targets. This
commit also rounds out `rust/Cargo.toml` with `documentation` /
`homepage` URLs and a `data-structures` category so docs.rs and the
crates.io categorization match the dual-purpose intent.

Captured the full analysis under `docs/case-studies/issue-92/`,
including CI/CD comparisons against the four AI pipeline templates.
Adds a single GitHub Pages deployment that publishes the DocFX-generated
docs for the `Foundation.Data.Doublets.Cli` library under `/csharp/`
alongside the `cargo doc` output for the `link-cli` crate under `/rust/`,
with a small landing page linking into both sub-sites. This lets external
.NET and Rust projects browse the same library surface that the `clink`
CLIs are composed of.

- Add `.github/workflows/docs.yml` covering DocFX build, `cargo doc`, site
  assembly, and `actions/deploy-pages` (single deployment per repo).
- Add `csharp/docfx.json`, `csharp/docs/index.md`, and `csharp/docs/toc.yml`
  to drive DocFX from the Library project's XML doc comments.
- Refresh the root, `csharp/`, and `rust/` READMEs so both the NuGet tool
  and the NuGet library, plus `cargo install`/`cargo add link-cli`, are
  documented side by side and linked to the published docs.
- Extend `.gitignore` with generated DocFX/`_site/` artifacts.
Documents the crates.io metadata refresh (description, documentation,
homepage, keywords, categories) and the README clarification that the
`link-cli` crate publishes both `[lib]` and `[[bin]]` targets, so the
Rust release pipeline's changelog-fragment guard accepts this PR.
Documents the new `Foundation.Data.Doublets.Cli` library package and
the trimmed-down `clink` dotnet tool so the changeset-driven release
workflow generates appropriate notes when this PR ships.
@konard konard changed the title [WIP] Double check we provide not only CLI, but also public library in NuGet and Crates IO Ship public library packages alongside CLI for both C# and Rust May 15, 2026
@konard konard marked this pull request as ready for review May 15, 2026 14:19
@konard
Copy link
Copy Markdown
Member Author

konard commented May 15, 2026

Working session summary

PR #93 is now ready for review with all CI checks green on commit fc40263.

Final state:

What shipped to address issue #92:

  1. C# project split → clink (dotnet tool) + Foundation.Data.Doublets.Cli (consumable library NuGet) sharing version via ProjectReference
  2. Release pipeline now publishes both packages, with multi-package badge support in create-github-release.mjs (24/24 tests passing)
  3. Rust Cargo.toml gained documentation/homepage/categories/keywords and a richer description so docs.rs and crates.io surface the library
  4. Unified GitHub Pages docs site combining DocFX (/csharp/) + cargo doc (/rust/) into a single deployment
  5. READMEs updated with both NuGet badges, Docs.rs badge, and dual install paths
  6. Changeset + Rust changelog fragment added for the release pipelines
  7. Full case study in docs/case-studies/issue-92/ with template snapshots and follow-up notes

This summary was automatically extracted from the AI working session output.

@konard
Copy link
Copy Markdown
Member Author

konard commented May 15, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost: $15.878948

📊 Context and tokens usage:

Claude Opus 4.7: (5 sub-sessions)

  1. 112.3K / 1M (11%) input tokens, 20.2K / 128K (16%) output tokens
  2. 116.9K / 1M (12%) input tokens, 17.9K / 128K (14%) output tokens
  3. 115.7K / 1M (12%) input tokens, 29.9K / 128K (23%) output tokens
  4. 115.1K / 1M (12%) input tokens, 19.0K / 128K (15%) output tokens
  5. 46.3K / 1M (5%) input tokens, 4.3K / 128K (3%) output tokens

Total: (17.3K new + 447.7K cache writes + 19.9M cache reads) input tokens, 121.3K output tokens, $15.871801 cost

Claude Haiku 4.5:

  • 5.2K / 200K (3%) input tokens, 391 / 64K (1%) output tokens

Total: 5.2K input tokens, 391 output tokens, $0.007147 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Main model: Claude Opus 4.7 (claude-opus-4-7)
  • Additional models:
    • Claude Haiku 4.5 (claude-haiku-4-5-20251001)

📎 Log file uploaded as Gist (6731KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Member Author

konard commented May 15, 2026

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard konard merged commit 5c592f3 into main May 15, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Double check we provide not only CLI, but also public library in NuGet and Crates IO

1 participant