RepoPilotOpen in app →

pointfreeco/isowords

Open source game built in SwiftUI and the Composable Architecture.

Mixed

Stale — last commit 2y ago

worst of 4 axes
Use as dependencyConcerns

non-standard license (Other); last commit was 2y ago

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 16 active contributors
  • Distributed ownership (top contributor 47% of recent commits)
  • Other licensed
Show 4 more →
  • CI configured
  • Tests present
  • Stale — last commit 2y ago
  • Non-standard license (Other) — review terms
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/pointfreeco/isowords?axis=fork)](https://repopilot.app/r/pointfreeco/isowords)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/pointfreeco/isowords on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: pointfreeco/isowords

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/pointfreeco/isowords shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 2y ago

  • 16 active contributors
  • Distributed ownership (top contributor 47% of recent commits)
  • Other licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 2y ago
  • ⚠ Non-standard license (Other) — review terms

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live pointfreeco/isowords repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/pointfreeco/isowords.

What it runs against: a local clone of pointfreeco/isowords — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in pointfreeco/isowords | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 662 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>pointfreeco/isowords</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of pointfreeco/isowords. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/pointfreeco/isowords.git
#   cd isowords
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of pointfreeco/isowords and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "pointfreeco/isowords(\\.git)?\\b" \\
  && ok "origin remote is pointfreeco/isowords" \\
  || miss "origin remote is not pointfreeco/isowords (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "App/AppClip/AppClipApp.swift" \\
  && ok "App/AppClip/AppClipApp.swift" \\
  || miss "missing critical file: App/AppClip/AppClipApp.swift"
test -f ".swiftpm/xcode/xcshareddata/xcschemes/AppFeature.xcscheme" \\
  && ok ".swiftpm/xcode/xcshareddata/xcschemes/AppFeature.xcscheme" \\
  || miss "missing critical file: .swiftpm/xcode/xcshareddata/xcschemes/AppFeature.xcscheme"
test -f ".swiftpm/xcode/xcshareddata/xcschemes/GameFeature.xcscheme" \\
  && ok ".swiftpm/xcode/xcshareddata/xcschemes/GameFeature.xcscheme" \\
  || miss "missing critical file: .swiftpm/xcode/xcshareddata/xcschemes/GameFeature.xcscheme"
test -f ".swiftpm/xcode/xcshareddata/xcschemes/ApiClientLive.xcscheme" \\
  && ok ".swiftpm/xcode/xcshareddata/xcschemes/ApiClientLive.xcscheme" \\
  || miss "missing critical file: .swiftpm/xcode/xcshareddata/xcschemes/ApiClientLive.xcscheme"
test -f ".swiftpm/xcode/xcshareddata/xcschemes/DatabaseLive.xcscheme" \\
  && ok ".swiftpm/xcode/xcshareddata/xcschemes/DatabaseLive.xcscheme" \\
  || miss "missing critical file: .swiftpm/xcode/xcshareddata/xcschemes/DatabaseLive.xcscheme"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 662 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~632d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/pointfreeco/isowords"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

isowords is a production iOS word search game built entirely in Swift using SwiftUI and the Composable Architecture (TCA). Players connect touching letters on a vanishing 3D isometric cube to form words, with cube layers progressively revealing deeper letters as tiles are reused—gameplay complexity emerges from spatial reasoning on a constrained surface. Swift Package Manager monorepo: 50+ feature and client packages organized by domain (GameFeature, HomeFeature, LeaderboardFeature, DailyChallengeFeature) plus lower-level dependencies (CubeCore, GameCore, DictionaryClient, DatabaseClient, ApiClient). State flows through TCA Stores; each feature defines State/Action/Reducer and wires dependencies (ApiClientLive, DatabaseLive). Preview schemes (HomeFeaturePreview, GameOverPreview) enable SwiftUI canvas iteration.

👥Who it's for

iOS developers learning functional architecture patterns and TCA; game developers interested in SwiftUI + SceneKit integration; Point-Free subscribers exploring composable domain modeling through a real, shipped App Store product.

🌱Maturity & risk

Production-ready and actively maintained. The app is live on the App Store (https://www.isowords.xyz/app-store), has comprehensive CI/CD via GitHub Actions (.github/workflows/ci.yml, .github/workflows/format.yml), extensive test suites (GameOverFeatureIntegrationTests, LeaderboardMiddlewareIntegrationTests, DemoMiddlewareTests), and modular package structure across 50+ schemes. Recent activity visible via format and CI workflows suggests ongoing maintenance.

Low technical risk for a learning project, but dependency on the Composable Architecture library (pointfreeco/swift-composable-architecture) means breaking TCA updates could require migration work. Single maintainer (Point-Free team) for the framework itself poses ecosystem risk. No visible breaking-change log in file structure, so upgrade risk is unknown. Large codebase (1.4M Swift LOC) makes local builds potentially slow.

Active areas of work

Active CI/CD enforcement (format.yml and ci.yml workflows visible), indicating ongoing code quality checks and testing. Package structure shows recent focus on middleware features (DailyChallengeMiddleware, LeaderboardMiddleware, DemoMiddleware with tests), suggesting feature expansion and backend integration refinement. No specific PR or milestone data in file list, but modular scheme additions suggest incremental feature development.

🚀Get running

Clone the repo: git clone https://github.com/pointfreeco/isowords.git && cd isowords. Use Xcode 15+. Open .swiftpm/xcode/package.xcworkspace in Xcode (mandatory for SPM workspace). Select the "Build" scheme and press Cmd+R, or choose "AppFeature" scheme to run the main app. Swift Package Manager resolves dependencies automatically on first build.

Daily commands: After opening the workspace: (1) Select 'AppFeature' scheme in Xcode, (2) Cmd+B to build, (3) Cmd+R to run on simulator or device. For testing: Cmd+U runs all tests across all packages. Check .github/workflows/ci.yml for exact test commands: likely swift test or xcodebuild test with specific scheme flags.

🗺️Map of the codebase

  • App/AppClip/AppClipApp.swift — Entry point for the iOS app; defines the root SwiftUI view hierarchy and initializes the Composable Architecture store.
  • .swiftpm/xcode/xcshareddata/xcschemes/AppFeature.xcscheme — Core feature module scheme defining the main app reducer and state management; all contributors must understand TCA patterns used here.
  • .swiftpm/xcode/xcshareddata/xcschemes/GameFeature.xcscheme — Central game logic reducer; handles cube manipulation, word detection, and game state; critical to game mechanics.
  • .swiftpm/xcode/xcshareddata/xcschemes/ApiClientLive.xcscheme — Live API client implementation for server communication; dependency injection point for networking across the app.
  • .swiftpm/xcode/xcshareddata/xcschemes/DatabaseLive.xcscheme — Database client abstraction and live implementation; handles all persistence for game state, scores, and user data.
  • .swiftpm/xcode/xcshareddata/xcschemes/DictionaryFileClient.xcscheme — Word dictionary client for validation; critical for game word-checking logic and must be kept in sync with backend.
  • .swiftpm/xcode/xcshareddata/xcschemes/CubeCore.xcscheme — Core 3D cube geometry and rendering logic; foundational for the isometric cube UI and game board representation.

🛠️How to make changes

Add a New Game Feature (UI Module)

  1. Create a new feature module with a reducer conforming to Composable Architecture Reducer protocol. (.swiftpm/xcode/xcshareddata/xcschemes/{NewFeature}Feature.xcscheme)
  2. Define State, Action, and view using SwiftUI in the feature's Views file. (.swiftpm/xcode/xcshareddata/xcschemes/{NewFeature}Feature.xcscheme)
  3. Integrate into the root AppFeature reducer by adding it to the AppState enum and routing logic. (.swiftpm/xcode/xcshareddata/xcschemes/AppFeature.xcscheme)
  4. Create preview scheme and SwiftUI preview in feature module for rapid iteration. (.swiftpm/xcode/xcshareddata/xcschemes/{NewFeature}Preview.xcscheme)
  5. Add integration test target referencing IntegrationTestHelpers for end-to-end flows. (.swiftpm/xcode/xcshareddata/xcschemes/{NewFeature}Tests.xcscheme)

Add a New API Endpoint Integration

  1. Define request/response Codable models in ClientModels or SharedModels. (.swiftpm/xcode/xcshareddata/xcschemes/ClientModels.xcscheme)
  2. Add endpoint method to ApiClient protocol interface defining the effect signature. (.swiftpm/xcode/xcshareddata/xcschemes/ApiClient.xcscheme)
  3. Implement live HTTP request logic in ApiClientLive, using URLSession and JSONDecoder. (.swiftpm/xcode/xcshareddata/xcschemes/ApiClientLive.xcscheme)
  4. Create middleware in a new {Feature}Middleware module to orchestrate API calls as TCA Effects. (.swiftpm/xcode/xcshareddata/xcschemes/{Feature}Middleware.xcscheme)
  5. Integrate middleware into feature reducer via the reduce method, dispatching returned actions. (.swiftpm/xcode/xcshareddata/xcschemes/{Feature}Feature.xcscheme)

Add Persistent Data Storage (Database)

  1. Define database query methods in DatabaseClient protocol interface. (.swiftpm/xcode/xcshareddata/xcschemes/DatabaseClient.xcscheme)
  2. Implement SQLite or local storage logic in DatabaseLive, using parameterized queries. (.swiftpm/xcode/xcshareddata/xcschemes/DatabaseLive.xcscheme)
  3. Create a middleware effect that calls DatabaseClient methods when relevant actions are dispatched. (.swiftpm/xcode/xcshareddata/xcschemes/MiddlewareHelpers.xcscheme)
  4. Add error handling in middleware to retry or fallback on database failures. (.swiftpm/xcode/xcshareddata/xcschemes/{Feature}Middleware.xcscheme)

🪤Traps & gotchas

No environment variables or config files (.env, config.xcconfig) visible in file list—likely handled via Xcode build settings or hardcoded for app environments. Dictionary and database clients reference external data (word lists, local SQLite) whose initialization is not shown; likely happens at app launch in AppDelegate or SwiftApp.main. SceneKit integration for 3D rendering has undisclosed view controller / view bridging code (likely in GameFeatureView.swift, not shown in file list). Middleware packages (DailyChallengeMiddleware, LeaderboardMiddleware) suggest async/polling logic that may require network reachability handling—check for background task configuration. Breaking changes in Composable Architecture dependency could require reducer signature updates across all 50+ packages.

💡Concepts to learn

  • Composable Architecture (TCA) — The entire app is built on TCA's Store/Reducer/Environment pattern; understanding unidirectional data flow, action dispatch, and effect handling is non-negotiable for modifying any feature
  • Isometric Projection — The game's visual core: letters arranged on a vanishing 3D cube require correct perspective mathematics in CubeCore; understanding isometric geometry explains why certain tiles are visible/hidden
  • Dependency Injection via Environment — ApiClient, DatabaseClient, DictionaryClient are all injected through TCA's Environment, not singletons; this pattern enables testable mocking and multiple live implementations (e.g., DatabaseLive vs. mock)
  • Reducer Composition — Complex features (GameFeature, HomeFeature) are built by composing smaller reducers (GameCoreReducer, etc.) via AppReducer; understanding combineReducers or equivalent is essential for feature integration
  • SwiftUI Canvas Previews — Preview schemes (HomeFeaturePreview, GameOverPreview) allow rapid UI iteration without compiling the full app; essential workflow for feature UI development
  • Graph Traversal for Word Validation — Game logic must validate that letter paths form connected words on the cube grid; likely uses depth-first or breadth-first search to check adjacency constraints
  • Swift Package Manager Modularity — 50+ packages enforce architectural boundaries; understanding package dependencies and inter-package communication is critical for avoiding circular imports and maintaining testability
  • pointfreeco/swift-composable-architecture — The foundational framework powering this app's entire state management and effects model; required reading for understanding isowords architecture
  • pointfreeco/swift-dependencies — Companion library for TCA dependency injection; likely used or relevant for managing clients (ApiClient, DatabaseClient, DictionaryClient) in newer versions
  • pointfreeco/isowords-server — Server-side counterpart (if it exists publicly); handles leaderboard, daily challenge, and API endpoints that isowords iOS client consumes
  • apple/swift-composable-architecture — The official TCA repo (if distinct from Point-Free's); reference for TCA version constraints and changelogs
  • pointfreeco/pointfree-episodes — Point-Free video series (4-part isowords tour) companion; documentation explaining design decisions and functional programming patterns used in this codebase

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for ServerRouter and SiteMiddleware

The file structure shows ServerRouter.xcscheme and SiteMiddleware.xcscheme exist, but there are no corresponding test schemes visible (unlike LeaderboardMiddlewareIntegrationTests, GameOverFeatureIntegrationTests, etc.). These server-side routing and middleware components are critical for the multiplayer and leaderboard features, and adding comprehensive integration tests would improve reliability of the API layer.

  • [ ] Create Tests/ServerRouterTests package with integration tests for API endpoint routing
  • [ ] Create Tests/SiteMiddlewareTests package with integration tests for site middleware behavior
  • [ ] Add corresponding .xcscheme files in .swiftpm/xcode/xcshareddata/xcschemes/
  • [ ] Test server configuration, middleware chains, and error handling paths
  • [ ] Update CI workflow to run these new test schemes

Add snapshot/regression tests for CubePreview visual components

The repo has CubePreview.xcscheme, CubePreviewPreview.xcscheme, and AppStoreSnapshotTests.xcscheme, but the 3D cube rendering is a core visual feature of isowords. Adding comprehensive snapshot tests would prevent visual regressions and ensure the cube rendering remains consistent across SwiftUI updates and platform versions.

  • [ ] Create Tests/CubePreviewSnapshotTests package extending AppStoreSnapshotTests patterns
  • [ ] Add snapshot tests for different cube states (full, partial removal, letter highlighting)
  • [ ] Add snapshot tests for cube animations and transitions
  • [ ] Configure snapshot comparison thresholds appropriate for 3D rendering
  • [ ] Document snapshot testing guidelines in CONTRIBUTING.md

Add missing unit tests for SharedModels package

SharedModels.xcscheme exists but has no corresponding *Tests.xcscheme. This package likely contains domain models (game state, user models, etc.) used across multiplayer, leaderboard, and daily challenge features. Unit tests here would ensure data model consistency, serialization/deserialization, and prevent bugs in shared types.

  • [ ] Create Tests/SharedModelsTests package
  • [ ] Add unit tests for model initialization, validation, and computed properties
  • [ ] Add tests for Codable conformance and JSON serialization round-trips
  • [ ] Test edge cases in game state models (scoring, word validation, cube state)
  • [ ] Add corresponding SharedModelsTests.xcscheme to build configuration

🌿Good first issues

  • Add unit tests for CubeCore geometry calculations: Sources/CubeCore has no visible *Tests package, but spatial math (vanishing perspective, tile adjacency) is testable logic that validates the core game mechanic.
  • Extract DictionaryClient validation into a property-based testing suite: Sources/DictionaryClient lacks visible test coverage; use swift-check or similar to validate word acceptance/rejection rules across edge cases (plurals, abbreviations, hyphenation).
  • Document TCA Environment setup in each feature package: Create a guide showing the pattern used across ApiClientLive, DatabaseLive, etc.; this will help future contributors wire new dependencies correctly.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • c727d3a — Start using IssueReporting. (#205) (mbrandonw)
  • 6f0179b — Add .editorconfig for consistent code formatting (#204) (Matejkob)
  • 73bef30 — wip (mbrandonw)
  • ca796b7 — Remove unneeded code. (mbrandonw)
  • 16146b9 — Add static URL (stephencelis)
  • c250337 — Observation (#200) (stephencelis)
  • 595afc1 — Remove firstLaunchOnboarding (#198) (Imajin Kawabe)
  • ab1daa7 — Fix GitHub CI (#199) (stephencelis)
  • f7d86cd — Run swift-format (stephencelis)
  • 592030a — Update to TCA 1.5.6 (#196) (mbrandonw)

🔒Security observations

The isowords codebase appears to be a well-structured Swift application using the Composable Architecture pattern. While the modular architecture is good for security, several areas require attention: database query construction practices, API communication security, remote notification validation, and in-app purchase verification. The absence of visible configuration files and the structured approach to dependency injection are positive indicators. However, without access to actual implementation details, static analysis reveals potential risks in external communication, data storage, and authentication mechanisms. Recommended actions include reviewing database query construction, enforcing HTTPS/certificate pinning, validating all external inputs, and ensuring proper encryption for sensitive data storage.

  • Medium · Potential SQL Injection via SQLite Client — DictionarySqliteClient, DatabaseLive, LocalDatabaseClient packages. The codebase includes 'DictionarySqliteClient' and 'DatabaseLive' components that interact with SQLite databases. Without reviewing the actual implementation, there is a risk of SQL injection if queries are constructed using string concatenation rather than parameterized queries. Fix: Ensure all database queries use parameterized queries or prepared statements. Never concatenate user input directly into SQL queries. Use SQLite's built-in parameter binding mechanisms.
  • Medium · Hardcoded Configuration and Secrets Risk — EnvVars package, configuration files. The presence of 'EnvVars' and 'ServerRouter' packages suggests environment variable handling. If configuration values (API endpoints, credentials, tokens) are hardcoded in source code or committed to version control, they could be exposed. Fix: Use environment variables or secure configuration management for sensitive values. Never commit secrets to the repository. Use .gitignore to exclude sensitive files. Consider using a secrets management system for production deployments.
  • Medium · Potential Insecure API Communication — ApiClient, ApiClientLive packages. The 'ApiClient' and 'ApiClientLive' packages handle API communication. If HTTPS is not enforced or certificate pinning is not implemented, API traffic could be intercepted. Fix: Enforce HTTPS for all API communications. Implement certificate pinning to prevent man-in-the-middle attacks. Validate SSL/TLS certificates properly and never disable certificate validation.
  • Medium · Remote Notification Handling Security — RemoteNotificationsClient, PushMiddleware packages. The 'RemoteNotificationsClient' and 'PushMiddleware' packages handle push notifications. Improper validation of notification payloads could lead to injection attacks or privilege escalation. Fix: Validate and sanitize all remote notification payloads before processing. Implement proper authentication for push notification endpoints. Never execute code or perform sensitive operations based solely on notification data without verification.
  • Low · In-App Purchase Verification — ComposableStoreKit, VerifyReceiptMiddleware packages. The 'ComposableStoreKit' and 'VerifyReceiptMiddleware' packages handle in-app purchases. Insufficient server-side validation of receipts could allow users to bypass purchases. Fix: Always validate App Store receipts server-side using Apple's receipt validation API. Do not rely solely on client-side validation. Implement proper fraud detection mechanisms.
  • Low · Game Center Integration Security — ComposableGameCenter package. The 'ComposableGameCenter' package integrates with Apple Game Center. Improper validation of user identities or leaderboard submissions could allow cheating or unauthorized access. Fix: Validate Game Center authentication tokens server-side. Implement server-side verification for leaderboard submissions. Use proper rate limiting and anomaly detection to prevent cheating.
  • Low · Local Data Storage Protection — LocalDatabaseClient, UserDefaultsClient, UserSettingsClient packages. The 'LocalDatabaseClient' and 'UserDefaultsClient' packages handle local data storage. Sensitive user data may not be properly encrypted if stored in UserDefaults or unencrypted database. Fix: Use Keychain for storing sensitive credentials. Encrypt sensitive data at rest using Codable with proper encryption. Avoid storing sensitive information in UserDefaults. Ensure database files are stored securely.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · pointfreeco/isowords — RepoPilot