Skip to content

release: prepare v1.2.0#75

Merged
gaelic-ghost merged 8 commits into
mainfrom
workspace/git-facts
May 9, 2026
Merged

release: prepare v1.2.0#75
gaelic-ghost merged 8 commits into
mainfrom
workspace/git-facts

Conversation

@gaelic-ghost
Copy link
Copy Markdown
Owner

@gaelic-ghost gaelic-ghost commented May 9, 2026

Release

  • prepares v1.2.0 from branch workspace/git-facts
  • keeps protected main updates behind pull request review and CI
  • release tag v1.2.0 was created locally before this PR so the reviewed release candidate is preserved exactly

Review Loop

Before merge, scripts/repo-maintenance/release.sh watches CI and stops on review comments unless the maintainer has already addressed or resolved them and reruns with --review-comments-addressed.

Summary by CodeRabbit

  • New Features

    • Introduced WorktreeSnapshot to represent working-directory and Git facts
    • Added worktree-based thread grouping, filtering, and selection in the Library
    • New queries to list threads by worktree or repository origin
  • Documentation

    • Bumped baseline to v1.2.0 and expanded README/ROADMAP and observables/docs for library selection, snapshots, and workspace permission notes
  • Tests

    • Added tests covering worktree identity, grouping, and selection behaviors

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c843bc8f-811f-4ca3-9175-4a539d5da163

📥 Commits

Reviewing files that changed from the base of the PR and between c612eb9 and f97497d.

📒 Files selected for processing (4)
  • ROADMAP.md
  • Sources/SwiftASB/Public/CodexWorkspace.swift
  • Tests/SwiftASBTests/Public/CodexAppServerLibraryTests.swift
  • Tests/SwiftASBTests/Public/CodexWorkspaceTests.swift
✅ Files skipped from review due to trivial changes (2)
  • Tests/SwiftASBTests/Public/CodexWorkspaceTests.swift
  • ROADMAP.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • Tests/SwiftASBTests/Public/CodexAppServerLibraryTests.swift
  • Sources/SwiftASB/Public/CodexWorkspace.swift

📝 Walkthrough

Walkthrough

This PR introduces CodexWorkspace.WorktreeSnapshot as a new public data type to model project identity via Git origin or current directory, refactors ProjectInfo to derive identity through that snapshot, expands CodexAppServer.Library with worktree-aware grouping and thread query methods, exposes worktree properties across thread and session snapshots, includes comprehensive tests, and updates all documentation and version baselines to v1.2.0.

Changes

Worktree Snapshot and Library Expansion

Layer / File(s) Summary
Data Contract: WorktreeSnapshot and Identity
Sources/SwiftASB/Public/CodexWorkspace.swift
New WorktreeSnapshot struct encapsulates project identity (source, display name, directory path) and optional Git repository facts. ProjectInfo is refactored to construct WorktreeSnapshot first, then derive id, identitySource, displayName, currentDirectoryPath, and repository from it. RepositoryInfo gains computed hasFacts and shortSHA helpers.
Library State: Worktree Grouping and Selection
Sources/SwiftASB/Public/CodexAppServer+Library.swift
Library now stores worktreeGroups (computed during visible-state application by grouping unarchived threads by repository origin) and exposes selectedWorktree and selectedRepository as computed properties derived from the currently selected thread.
Snapshot Exposure: Worktree Properties
Sources/SwiftASB/Public/CodexAppServer+Library.swift, Sources/SwiftASB/Public/CodexAppServer+ThreadLifecycle.swift, Sources/SwiftASB/Public/CodexWorkspace.swift
ThreadSnapshot, ThreadGroup, and ThreadInfo expose a worktree computed property sourced from projectInfo.worktree. SessionSnapshot is updated to include a worktree property sourced from the session thread's project info.
Query and Filter APIs
Sources/SwiftASB/Public/CodexAppServer+Library.swift
New public methods threads(in:includeArchived:), threads(inWorktreeID:includeArchived:), and threads(inRepositoryOriginURL:includeArchived:) enable filtering thread snapshots by worktree or repository origin.
API Documentation
Sources/SwiftASB/SwiftASB.docc/SwiftUIObservableCompanions.md
Expanded section describing CodexAppServer.Library responsibilities, enumerated snapshot types including WorktreeSnapshot, specified selection behavior and reload triggers, and documented usage recommendations for worktreeGroups and thread query APIs.
Tests: Snapshot Behavior
Tests/SwiftASBTests/Public/CodexWorkspaceTests.swift
New test file verifies WorktreeSnapshot derives identity from Git repository facts when present, and falls back to current directory when facts are absent.
Tests: Library Integration
Tests/SwiftASBTests/Public/CodexAppServerLibraryTests.swift
Updated fixtures with gitSHA parameter and enhanced assertions for worktree metadata. New test verifies worktreeGroups and repository-filtered queries work independently of visible grouping, and confirms selectedWorktree/selectedRepository reflect current selection.
Version and Manifest Updates
README.md, ROADMAP.md, docs/maintainers/*
Version baseline bumped from v1.1.4 to v1.2.0. README usage guidance expanded to enumerate library capabilities. ROADMAP updated with app-wide observable companion details, revised priority ordering, deferred work items, and release references. API audit and symbol inventory documents refreshed with new type counts and public API additions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • gaelic-ghost/SwiftASB#72: Both PRs modify the same public models and library code (CodexWorkspace, CodexAppServer+Library.swift, CodexAppServer+ThreadLifecycle.swift), promoting app-server project/worktree identity into model types and adding thread-level project/worktree properties plus library grouping/query helpers.

Suggested labels

enhancement

Poem

🐰 A snapshot of the worktree blooms bright,
Identity flowing from repository light—
GroupedBy origin, filtered with care,
The library now knows each thread's layer,
v1.2.0 hops into view! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'release: prepare v1.2.0' is fully related to the changeset, which updates documentation, adds worktree-related APIs, and increments the version baseline from v1.1.4 to v1.2.0.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch workspace/git-facts

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c612eb931e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +185 to 187
if let originURL = self.repository?.originURL, !originURL.isEmpty {
self.id = originURL
self.identitySource = .gitOrigin
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Distinguish worktrees by cwd instead of repository origin

WorktreeSnapshot.id is set to originURL whenever Git metadata exists, but Library.threads(inWorktreeID:) and worktreeGroups key off that ID, so two different checkouts/worktrees of the same repository collapse into one logical “worktree.” In that scenario, callers cannot target a single worktree (they always get all threads for that origin), which defeats the new worktree-specific APIs and can mix branch-specific UI/state across separate directories.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
ROADMAP.md (1)

192-206: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix duplicate ordered-list numbering in current priority list.

Line 201 repeats 10. after Line 193 already uses 10.. Renumbering avoids ambiguous references in plaintext diffs and maintainer discussions.

✏️ Suggested renumbering
-10. Flesh out archive-aware retention and eviction beyond the current list-driven
+11. Flesh out archive-aware retention and eviction beyond the current list-driven
   archive-state drift correction.
-11. Add any sharper binary-discovery diagnostics we want alongside the
+12. Add any sharper binary-discovery diagnostics we want alongside the
   current-reviewed compatibility window before a broader compatibility release.
-12. Revisit whether a convenience `run(...)` API is earned only after the
+13. Revisit whether a convenience `run(...)` API is earned only after the
   lower-level lifecycle has more production mileage.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ROADMAP.md` around lines 192 - 206, The ordered list has a duplicate "10."
entry; update the second "10." (the item starting "Flesh out archive-aware
retention and eviction...") to "11." and increment the subsequent list numbers
accordingly (change the existing "11." "Add any sharper..." to "12." and the
"12." "Revisit whether a convenience `run(...)` API..." to "13.") so the
sequence is unique and unambiguous while preserving the exact item text.
Sources/SwiftASB/Public/CodexWorkspace.swift (1)

183-199: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize empty/whitespace Git facts before computing worktree identity.

If Codex sends ""/whitespace in Git fields, hasFacts can become true while identity still falls back inconsistently. Treating blank strings as nil keeps hasFacts, hasRepositoryFacts, and identity derivation aligned.

🧩 Suggested fix
 public struct RepositoryInfo: Sendable, Equatable {
@@
     public init(
         originURL: String? = nil,
         branch: String? = nil,
         sha: String? = nil
     ) {
-        self.originURL = originURL
-        self.branch = branch
-        self.sha = sha
+        self.originURL = Self.normalizedFact(originURL)
+        self.branch = Self.normalizedFact(branch)
+        self.sha = Self.normalizedFact(sha)
     }
@@
     internal var normalized: Self? {
         isEmpty ? nil : self
     }
+
+    private static func normalizedFact(_ value: String?) -> String? {
+        guard let trimmed = value?.trimmingCharacters(in: .whitespacesAndNewlines),
+              !trimmed.isEmpty else {
+            return nil
+        }
+        return trimmed
+    }
 }

Also applies to: 243-249

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/SwiftASB/Public/CodexWorkspace.swift` around lines 183 - 199, The
repository normalization must treat empty or whitespace-only Git fields as nil
so hasFacts/hasRepositoryFacts and identity derivation stay consistent: update
the normalization logic used when assigning self.repository (and any other
places like the block around lines 243-249) so that repository?.normalized trims
string fields and converts ""/whitespace-only values to nil before you evaluate
repository?.hasFacts, compute id/identitySource, or call
Self.displayName(forGitOriginURL:); ensure the same nil-normalization is applied
wherever Repository.normalized is used so hasRepositoryFacts accurately reflects
presence of real Git data.
🧹 Nitpick comments (1)
Tests/SwiftASBTests/Public/CodexAppServerLibraryTests.swift (1)

251-267: ⚡ Quick win

Add direct checks for threads(in:) and threads(inWorktreeID:) to complete API coverage.

The new test already validates threads(inRepositoryOriginURL:); adding direct assertions for the other two new selectors would better lock in parity across the full public worktree query surface.

♻️ Suggested test additions
         `#expect`(library.threads(inRepositoryOriginURL: "https://github.com/gaelic-ghost/SwiftASB.git").map(\.id) == [
             "thread-active",
         ])
+        let repoWorktree = try `#require`(
+            library.worktreeGroups.first(where: { $0.id == "https://github.com/gaelic-ghost/SwiftASB.git" })?.worktree
+        )
+        `#expect`(library.threads(in: repoWorktree).map(\.id) == ["thread-active"])
+        `#expect`(library.threads(inWorktreeID: repoWorktree.id).map(\.id) == ["thread-active"])
         `#expect`(library.threads(
             inRepositoryOriginURL: "https://github.com/gaelic-ghost/SwiftASB.git",
             includeArchived: true
         ).map(\.id) == [
             "thread-active",
             "thread-archived",
         ])
+        `#expect`(library.threads(in: repoWorktree, includeArchived: true).map(\.id) == [
+            "thread-active",
+            "thread-archived",
+        ])
+        `#expect`(library.threads(inWorktreeID: repoWorktree.id, includeArchived: true).map(\.id) == [
+            "thread-active",
+            "thread-archived",
+        ])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/SwiftASBTests/Public/CodexAppServerLibraryTests.swift` around lines 251
- 267, Add direct assertions calling library.threads(in:) and
library.threads(inWorktreeID:) to mirror the existing repository-origin tests:
call library.threads(in: <Repository> or appropriate param) and
library.threads(inWorktreeID: "<worktree-id>") and assert their .map(\.id)
returns ["thread-active"] for default and ["thread-active","thread-archived"]
when includeArchived: true; reference the library variable and the methods
threads(in:) and threads(inWorktreeID:) so the test covers both selectors
alongside the existing threads(inRepositoryOriginURL:) checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@ROADMAP.md`:
- Around line 192-206: The ordered list has a duplicate "10." entry; update the
second "10." (the item starting "Flesh out archive-aware retention and
eviction...") to "11." and increment the subsequent list numbers accordingly
(change the existing "11." "Add any sharper..." to "12." and the "12." "Revisit
whether a convenience `run(...)` API..." to "13.") so the sequence is unique and
unambiguous while preserving the exact item text.

In `@Sources/SwiftASB/Public/CodexWorkspace.swift`:
- Around line 183-199: The repository normalization must treat empty or
whitespace-only Git fields as nil so hasFacts/hasRepositoryFacts and identity
derivation stay consistent: update the normalization logic used when assigning
self.repository (and any other places like the block around lines 243-249) so
that repository?.normalized trims string fields and converts ""/whitespace-only
values to nil before you evaluate repository?.hasFacts, compute
id/identitySource, or call Self.displayName(forGitOriginURL:); ensure the same
nil-normalization is applied wherever Repository.normalized is used so
hasRepositoryFacts accurately reflects presence of real Git data.

---

Nitpick comments:
In `@Tests/SwiftASBTests/Public/CodexAppServerLibraryTests.swift`:
- Around line 251-267: Add direct assertions calling library.threads(in:) and
library.threads(inWorktreeID:) to mirror the existing repository-origin tests:
call library.threads(in: <Repository> or appropriate param) and
library.threads(inWorktreeID: "<worktree-id>") and assert their .map(\.id)
returns ["thread-active"] for default and ["thread-active","thread-archived"]
when includeArchived: true; reference the library variable and the methods
threads(in:) and threads(inWorktreeID:) so the test covers both selectors
alongside the existing threads(inRepositoryOriginURL:) checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 57e26f59-fa2c-4922-ba01-9ea5f0dc980e

📥 Commits

Reviewing files that changed from the base of the PR and between 8214210 and c612eb9.

📒 Files selected for processing (10)
  • README.md
  • ROADMAP.md
  • Sources/SwiftASB/Public/CodexAppServer+Library.swift
  • Sources/SwiftASB/Public/CodexAppServer+ThreadLifecycle.swift
  • Sources/SwiftASB/Public/CodexWorkspace.swift
  • Sources/SwiftASB/SwiftASB.docc/SwiftUIObservableCompanions.md
  • Tests/SwiftASBTests/Public/CodexAppServerLibraryTests.swift
  • Tests/SwiftASBTests/Public/CodexWorkspaceTests.swift
  • docs/maintainers/v1-public-api-audit.md
  • docs/maintainers/v1-public-api-symbol-inventory.md

@gaelic-ghost gaelic-ghost merged commit 26aec7d into main May 9, 2026
2 checks passed
@gaelic-ghost gaelic-ghost deleted the workspace/git-facts branch May 9, 2026 00:43
@coderabbitai coderabbitai Bot mentioned this pull request May 9, 2026
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.

1 participant