Skip to content

Commit 1c028fb

Browse files
authored
docs: sync Swift package maintainer guidance (#18)
1 parent bb84daf commit 1c028fb

23 files changed

Lines changed: 1031 additions & 32 deletions
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Validate Repo Maintenance
2+
3+
# Branch protection should require the Actions check context `validate`.
4+
# GitHub exposes the job check run by this job name, not by the workflow title.
5+
6+
on:
7+
pull_request:
8+
push:
9+
branches:
10+
- main
11+
12+
jobs:
13+
validate:
14+
name: validate
15+
runs-on: macos-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- name: Install Swift repo-maintenance tools
19+
run: brew install swiftformat swiftlint
20+
- name: Run repo-maintenance validation
21+
run: bash scripts/repo-maintenance/validate-all.sh

.swiftformat

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Exported from Gale's SwiftFormat for Xcode settings and curated for repo use.
2+
# This file is the repository source of truth for formatting. If the host app
3+
# configuration changes later, re-export from the shared SwiftFormat settings
4+
# and review the diff before importing it back into the app.
5+
6+
--rules andOperator,anyObjectProtocol,applicationMain,assertionFailures,blankLineAfterImports,blankLinesAfterGuardStatements,blankLinesAroundMark,blankLinesAtEndOfScope,blankLinesAtStartOfScope,blankLinesBetweenChainedFunctions,blankLinesBetweenImports,blankLinesBetweenScopes,braces,conditionalAssignment,consecutiveBlankLines,consecutiveSpaces,consistentSwitchCaseSpacing,docComments,docCommentsBeforeModifiers,duplicateImports,elseOnSameLine,emptyBraces,emptyExtensions,enumNamespaces,environmentEntry,extensionAccessControl,fileMacro,genericExtensions,headerFileName,hoistAwait,hoistPatternLet,hoistTry,indent,initCoderUnavailable,isEmpty,leadingDelimiters,linebreakAtEndOfFile,linebreaks,modifierOrder,noForceTryInTests,noForceUnwrapInTests,noGuardInTests,numberFormatting,opaqueGenericParameters,organizeDeclarations,preferFinalClasses,privateStateVariables,redundantAsync,redundantBackticks,redundantBreak,redundantClosure,redundantEquatable,redundantExtensionACL,redundantFileprivate,redundantGet,redundantInit,redundantInternal,redundantLet,redundantLetError,redundantMemberwiseInit,redundantNilInit,redundantObjc,redundantOptionalBinding,redundantParens,redundantPattern,redundantPublic,redundantRawValues,redundantReturn,redundantSelf,redundantSendable,redundantStaticSelf,redundantSwiftTestingSuite,redundantThrows,redundantType,redundantTypedThrows,redundantVariable,redundantViewBuilder,semicolons,simplifyGenericConstraints,sortDeclarations,sortImports,sortTypealiases,spaceAroundBraces,spaceAroundBrackets,spaceAroundComments,spaceAroundGenerics,spaceAroundOperators,spaceAroundParens,spaceInsideBrackets,spaceInsideComments,spaceInsideGenerics,spaceInsideParens,strongOutlets,strongifiedSelf,swiftTestingTestCaseNames,todos,trailingClosures,trailingCommas,trailingSpace,typeSugar,validateTestCases,void,wrap,wrapArguments,wrapAttributes,wrapLoopBodies,wrapMultilineFunctionChains,wrapSingleLineComments,yodaConditions
7+
8+
--acronyms ID,URL,UUID
9+
--allow-partial-wrapping true
10+
--anonymous-for-each convert
11+
--asset-literals visual-width
12+
--binary-grouping 4,8
13+
--line-between-guards false
14+
--category-mark "MARK: %c"
15+
--class-threshold 0
16+
--closing-paren balanced
17+
--closure-void remove
18+
--complex-attributes preserve
19+
--computed-var-attributes preserve
20+
--conditional-assignment after-property
21+
--date-format system
22+
--decimal-grouping 3,6
23+
--doc-comments before-declarations
24+
--else-position same-line
25+
--empty-braces no-space
26+
--enum-namespaces always
27+
--equatable-macro none
28+
--exponent-case lowercase
29+
--extension-acl on-extension
30+
--file-macro "#file"
31+
--func-attributes preserve
32+
--group-blank-lines true
33+
--guard-else auto
34+
--header ignore
35+
--hex-grouping 4,8
36+
--hex-literal-case uppercase
37+
--ifdef outdent
38+
--import-grouping alpha,access-control
39+
--indent 4
40+
--indent-case true
41+
--indent-strings false
42+
--inferred-types always
43+
--init-coder-nil false
44+
--line-after-marks true
45+
--linebreaks lf
46+
--mark-categories false
47+
--mark-class-threshold 40
48+
--mark-enum-threshold 40
49+
--mark-extension-threshold 40
50+
--mark-struct-threshold 40
51+
--max-width none
52+
--operator-func spaced
53+
--organization-mode type
54+
--organize-types actor,class,enum,struct
55+
--pattern-let hoist
56+
--prefer-synthesized-init-for-internal-structs never
57+
--property-types infer-locals-only
58+
--ranges no-space
59+
--redundant-async tests-only
60+
--redundant-throws tests-only
61+
--self remove
62+
--semicolons inline-only
63+
--short-optionals preserve-struct-inits
64+
--smart-tabs enabled
65+
--some-any true
66+
--sort-swiftui-properties alphabetize
67+
--stored-var-attributes preserve
68+
--struct-threshold 40
69+
--strip-unused-args always
70+
--suite-name-format standard-identifiers
71+
--test-case-name-format raw-identifiers
72+
--timezone system
73+
--trailing-commas always
74+
--trim-whitespace always
75+
--type-attributes preserve
76+
--type-blank-lines remove
77+
--type-body-marks preserve
78+
--type-delimiter space-after
79+
--class-threshold 40
80+
--enum-threshold 40
81+
--extension-threshold 40
82+
--void-type Void
83+
--wrap-arguments preserve
84+
--wrap-collections preserve
85+
--wrap-conditions preserve
86+
--wrap-effects preserve
87+
--wrap-return-type preserve
88+
--wrap-string-interpolation default
89+
--wrap-ternary default
90+
--wrap-type-aliases preserve
91+
--xcode-indentation disabled
92+
--yoda-swap always

.swiftlint.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Keep SwiftLint focused on non-formatting checks.
2+
# SwiftFormat owns visual shape in this repository.
3+
4+
excluded:
5+
- .build
6+
- .local
7+
8+
only_rules:
9+
- duplicate_imports
10+
- empty_count
11+
- fatal_error_message
12+
- force_try
13+
- force_unwrapping
14+
- unused_import
15+
16+
force_try:
17+
severity: warning
18+
19+
force_unwrapping:
20+
severity: warning

AGENTS.md

Lines changed: 138 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,159 @@
11
# AGENTS.md
22

3-
## Repository Expectations
3+
Repo-local guidance for maintaining SwiftASB, a Swift Package Manager library that wraps the local Codex app-server for Swift and SwiftUI clients.
4+
5+
## Repository Scope
6+
7+
### What This File Covers
8+
9+
- Use this file for all work at the SwiftASB repository root.
10+
- Treat this package as a library first: public API should be deliberate, documented, and tested.
11+
- Use Swift Package Manager as the source of truth for package structure, dependencies, products, targets, resources, and Swift language mode.
12+
- Treat the bundled Codex app-server v2 schema as the primary generated-wire source of truth.
13+
- Treat the generated wire layer as internal scaffolding, not the final public Swift API.
14+
15+
### Where To Look First
16+
17+
- Start with `Package.swift` for package graph, target, dependency, platform, and Swift language mode changes.
18+
- Use `Sources/SwiftASB/Public/` for public API shape and `Sources/SwiftASB/Protocol/`, `Sources/SwiftASB/Transport/`, and `Sources/SwiftASB/History/` for the main internal runtime surfaces.
19+
- Use `Sources/SwiftASB/Generated/CodexWire/Latest/` for the promoted generated v2 wire snapshot.
20+
- Use `Tests/SwiftASBTests/` for Swift Testing coverage.
21+
- Use `scripts/generate-wire-types.sh` for Codex schema-derived wire refreshes.
22+
- Use `scripts/repo-maintenance/` for repo-owned validation, shared sync, and release entrypoints.
23+
- Use `README.md`, `CONTRIBUTING.md`, `ROADMAP.md`, and `docs/maintainers/` for shipped behavior, contributor workflow, planned work, and durable design decisions.
24+
25+
## Working Rules
26+
27+
### Change Scope
28+
29+
- Prefer the simplest correct Swift that is easiest to read, reason about, and maintain.
30+
- Prefer value types for domain modeling.
31+
- Prefer concrete types internally and reserve protocols for real seams.
32+
- Mark classes `final` by default when reference semantics are required.
33+
- Keep dependency flow unidirectional and ownership obvious.
34+
- Prefer explicit, consistent, and unambiguous names.
35+
- Prefer synthesized conformances and memberwise initialization whenever they satisfy the real need.
36+
- Avoid ceremony, wrappers, or extra abstraction layers unless they solve a concrete package problem.
37+
- Keep operator-facing errors, warnings, and log strings descriptive and human-readable.
38+
39+
### Source of Truth
440

5-
- Use Swift Package Manager as the source of truth for package structure and dependencies.
641
- Prefer `swift package` CLI commands for structural changes whenever the command exists.
742
- Use `swift package add-dependency` to add dependencies instead of hand-editing package graphs.
843
- Use `swift package add-target` to add library, executable, or test targets.
944
- For package configuration not covered by CLI commands, update `Package.swift` intentionally and keep edits minimal.
1045
- Keep package graph updates together in the same change when structure changes.
11-
- Validate package changes with:
12-
- `swift build`
13-
- `swift test`
46+
- Keep `Package.swift` explicit about its package-wide Swift language mode; prefer `swiftLanguageModes: [.v6]` on current Swift 6-era manifests.
47+
- Treat `Package.resolved` and similar package-manager outputs as generated files; do not hand-edit them.
48+
- Keep package resources under the owning target tree, declare them intentionally, and load bundled resources through `Bundle.module`.
1449

15-
## Swift Package Workflow
50+
### Communication and Escalation
1651

52+
- For Swift, Apple-framework, Apple-platform, or Xcode-related tasks, read the relevant Apple or Swift documentation first before proposing or making changes.
53+
- If a public API change, generated-wire promotion, new dependency, or ownership change starts widening beyond the requested scope, surface that before implementing it.
54+
- If SwiftPM guidance drifts, use `sync-swift-package-guidance` to refresh or merge the package workflow baseline.
1755
- Use `bootstrap-swift-package` only when a new Swift package repo still needs to be created from scratch.
18-
- Use `sync-swift-package-guidance` when repo guidance for this package drifts and needs to be refreshed or merged forward.
19-
- Re-run `sync-swift-package-guidance` after substantial package-workflow or plugin updates so local guidance stays aligned.
2056
- Use `swift-package-build-run-workflow` for manifest, dependency, resource, build, and run work when `Package.swift` is the source of truth.
2157
- Use `swift-package-testing-workflow` for Swift Testing, XCTest holdouts, fixtures, package test diagnosis, and package test-plan work.
2258
- Prefer `xcode-build-run-workflow` or `xcode-testing-workflow` only when package work needs Xcode-managed SDK, toolchain, DocC, or test behavior.
23-
- Keep `Package.swift` explicit about its package-wide Swift language mode; prefer `swiftLanguageModes: [.v6]` on current Swift 6-era manifests.
24-
- Treat `Package.resolved` and similar package-manager outputs as generated files; do not hand-edit them.
25-
- Keep package resources under the owning target tree, declare them intentionally, and load bundled resources through `Bundle.module`.
59+
- Re-run `sync-swift-package-guidance` after substantial package-workflow or plugin updates so local guidance stays aligned.
2660

27-
## Swift Baseline
61+
## Commands
2862

29-
- For Swift, Apple-framework, Apple-platform, or Xcode-related tasks, read the relevant Apple or Swift documentation first before proposing or making changes.
30-
- Prefer the simplest correct Swift that is easiest to read, reason about, and maintain.
31-
- Prefer explicit, consistent, and unambiguous names.
32-
- Prefer synthesized conformances and memberwise initialization whenever they satisfy the real need.
33-
- Avoid ceremony, wrappers, or extra abstraction layers unless they solve a concrete package problem.
34-
- Keep operator-facing errors, warnings, and log strings descriptive and human-readable.
63+
### Setup
3564

36-
## Types and Architecture
65+
Use Swift 6.3 or newer on macOS 15 or newer. SwiftASB discovers the local Codex CLI from `PATH`, common Homebrew locations, or the npm global prefix.
3766

38-
- Prefer value types for domain modeling.
39-
- Prefer concrete types internally and reserve protocols for real seams.
40-
- Mark classes `final` by default when reference semantics are required.
41-
- Keep dependency flow unidirectional and ownership obvious.
42-
- Treat this package as a library first: public API should be deliberate, documented, and tested.
67+
```bash
68+
swift package resolve
69+
```
70+
71+
### Validation
72+
73+
Run the package checks before committing package changes:
74+
75+
```bash
76+
swift build
77+
swift test
78+
```
79+
80+
Run the repo-maintenance validation before release or maintainer-surface changes:
81+
82+
```bash
83+
bash scripts/repo-maintenance/validate-all.sh
84+
```
85+
86+
Check whitespace before staging:
87+
88+
```bash
89+
git diff --check
90+
```
91+
92+
### Optional Project Commands
93+
94+
Refresh generated Codex wire types through the maintainer entrypoint:
95+
96+
```bash
97+
scripts/generate-wire-types.sh
98+
```
99+
100+
Run the repo-maintenance shared sync entrypoint:
101+
102+
```bash
103+
bash scripts/repo-maintenance/sync-shared.sh
104+
```
105+
106+
Start a standard release from a feature branch with a clean committed worktree:
107+
108+
```bash
109+
bash scripts/repo-maintenance/release.sh --mode standard --version vX.Y.Z
110+
```
111+
112+
Validate DocC through Xcode when documentation changes:
113+
114+
```bash
115+
xcodebuild docbuild -scheme SwiftASB -destination generic/platform=macOS -derivedDataPath tmp/xcode-docc/DerivedData
116+
```
117+
118+
## Review and Delivery
119+
120+
### Review Expectations
121+
122+
- Keep package, docs, tests, and generated-wire surfaces aligned in the same branch when one change affects more than one of them.
123+
- Do not promote generated schema additions to public API just because they exist upstream; classify them as public now, observable-only for now, or internal-only before exposing them.
124+
- Keep README product-facing. Keep contributor workflow, local validation, live test flags, schema generation, DocC build commands, and release-prep details in `CONTRIBUTING.md` unless the README user needs them to consume the package.
125+
- PRs should identify the changed surface, explain any public API or docs boundary decision, and list the validation commands that ran.
126+
127+
### Definition of Done
128+
129+
- `swift build` and `swift test` pass for package changes unless the task is explicitly docs-only and no package behavior changed.
130+
- `bash scripts/repo-maintenance/validate-all.sh` passes for maintainer guidance, repo tooling, CI wrapper, or release setup changes.
131+
- Documentation reflects the actual shipped behavior, not aspirational API.
132+
- Live Codex runtime probes are described as observational when runtime behavior is nondeterministic.
133+
134+
## Safety Boundaries
135+
136+
### Never Do
137+
138+
- Do not hand-edit `Package.resolved`.
139+
- Do not hand-edit the promoted generated wire snapshot in `Sources/SwiftASB/Generated/CodexWire/Latest/`; use `scripts/generate-wire-types.sh`.
140+
- Do not reintroduce a promoted generated v1 batch unless Gale explicitly asks for that compatibility surface again.
141+
- Do not commit dumped local schema artifacts under `codex-schemas/` unless Gale explicitly asks to commit them.
142+
- Do not commit temporary derived schemas or raw or patched quicktype staging output under `tmp/`.
143+
- Do not treat the generated wire layer as public Swift API.
144+
- Do not use `xcodebuild` as the default package validation path when plain SwiftPM validation is enough.
145+
146+
### Ask Before
147+
148+
- Ask before changing the public API ownership model, release boundary, licensing terms, or Codex CLI compatibility window.
149+
- Ask before adding dependencies that are not first-party or top-tier Swift ecosystem packages.
150+
- Ask before changing the shape of promoted generated-wire output.
151+
- Ask before committing local schema dumps or temporary generated artifacts that are normally untracked.
152+
153+
## Local Overrides
154+
155+
- No nested `AGENTS.md` files are currently present below the repository root.
156+
- If a more specific `AGENTS.md` is added later, follow the closer file for its subtree while keeping this root guidance as the package-wide baseline.
43157

44158
## Codex App-Server Wire Workflow
45159

@@ -52,10 +166,3 @@
52166
- Keep `CodexWireInitializeResponse` hand-owned in its own dedicated Swift file next to the promoted generated v2 snapshot until the upstream v2 schema exposes that type directly.
53167
- Do not reintroduce a promoted generated v1 batch unless Gale explicitly asks for that compatibility surface again.
54168
- Treat the generated wire layer as an internal scaffolding surface, not the final public Swift API.
55-
56-
## Testing and Tooling
57-
58-
- Use Swift Testing as the default test framework.
59-
- Avoid XCTest unless an external constraint requires it.
60-
- Use `swift build` and `swift test` as the default first-pass validation commands.
61-
- Use `xcodebuild` only when Apple-platform integration details need validation beyond plain SwiftPM.

CONTRIBUTING.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,19 @@ SwiftASB does not ship UI, but its observable companions are intended for SwiftU
7272

7373
### Verification
7474

75-
Run the package checks before committing:
75+
Run the package checks before committing package changes:
7676

7777
```bash
7878
swift build
7979
swift test
8080
```
8181

82+
Run the repo-maintenance validation before release, CI wrapper, maintainer guidance, or tooling changes:
83+
84+
```bash
85+
bash scripts/repo-maintenance/validate-all.sh
86+
```
87+
8288
Validate DocC through Xcode when documentation changes:
8389

8490
```bash
@@ -109,6 +115,22 @@ Check whitespace before staging:
109115
git diff --check
110116
```
111117

118+
### Maintainer Scripts
119+
120+
SwiftASB uses `scripts/repo-maintenance/` as the local-first maintainer surface. GitHub Actions stays a thin wrapper around these scripts, and branch protection should require the `validate` check context from `.github/workflows/validate-repo-maintenance.yml`.
121+
122+
Use the shared sync entrypoint for future managed repo-maintenance refreshes:
123+
124+
```bash
125+
bash scripts/repo-maintenance/sync-shared.sh
126+
```
127+
128+
Use the release entrypoint from a feature branch or isolated worktree with a clean committed worktree:
129+
130+
```bash
131+
bash scripts/repo-maintenance/release.sh --mode standard --version vX.Y.Z
132+
```
133+
112134
## Pull Request Expectations
113135

114136
PRs should identify the changed surface, explain any public API or docs boundary decision, and list the validation commands that ran. Use the `documentation` label for docs-only work and a more specific label when the code surface is the stronger signal.

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ Contributor validation commands, live test flags, and the Xcode DocC build comma
203203

204204
```text
205205
.
206+
├── .github/
207+
│ └── workflows/
206208
├── .spi.yml
207209
├── CONTRIBUTING.md
208210
├── Package.swift
@@ -222,6 +224,8 @@ Contributor validation commands, live test flags, and the Xcode DocC build comma
222224
│ ├── Public/
223225
│ └── Transport/
224226
└── scripts/
227+
├── generate-wire-types.sh
228+
└── repo-maintenance/
225229
```
226230

227231
## Release Notes
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Managed by maintain-project-repo. Do not hand-edit unless you also control the installer contract.
2+
REPO_MAINTENANCE_PROFILE="swift-package"
3+
REPO_MAINTENANCE_PROFILE_DESCRIPTION="Swift Package Manager repo-maintenance profile for library, tool, and package repos."

0 commit comments

Comments
 (0)