A local-first macOS todo app. GitHub searches and notifications, Slack, manual capture and MCP intake feed a ranked task list for each work profile. Copilot assesses changed tasks and prioritizes the selected profile's list using its instructions; unchanged runs reuse saved assessments and ordering.
The desktop keeps the native Mac shell, CLI authentication and revisioned SQLite storage. Existing tasks, completion and thread notes are retained.
Settings → Appearance offers all 57 themes from the Copilot App catalog, including GitHub and Fox, with Light, Dark and System modes. Changes apply immediately and persist across relaunch. GitHub dark remains the default.
Appearance stays separate from tasks and their backups. Desktop preferences use a local appearance.json file. See theme support for palette sources and catalog updates.
Download the latest GitHub-Projects-*-macOS-arm64.zip from GitHub Releases. Unzip it, then move GitHub Projects.app to Applications.
Releases support Apple silicon Macs running macOS 12 or newer. They are ad-hoc signed, not notarized, so macOS may require you to Control-click the app and choose Open on first launch.
Set the same version in package.json, src-tauri/Cargo.toml, and src-tauri/tauri.conf.json, then push a matching tag:
git tag v0.2.0
git push origin v0.2.0The tag starts a GitHub Actions build on an Apple silicon runner and publishes the app archive and SHA-256 checksum to a GitHub release. Standard GitHub-hosted runners are free for this public repository.
- Open Settings. Configure sources and the Task assessor and Task prioritizer, each with its own name, instructions and model. Changes save automatically; complete any invalid fields to save pending edits. The footer confirms when changes reach disk.
- Choose Run now. The app collects requests, reconciles task identity and completion, and asks Copilot to order all actionable tasks with reasons.
- Work down the list. Done is local; it does not submit a review, close an issue or acknowledge a notification.
- Optionally enable a cadence. Runs continue while the app is running, including hidden in the menu bar. An overdue schedule catches up once after sleep or relaunch; quitting stops it.
Manual tasks save offline immediately and join the ranking on the next run. A failed model call preserves new discoveries and the previous order, with unranked tasks visible. Coverage and run details holds source warnings and run failures without a duplicate error banner above the task list. Storage and local action failures stay visible separately. Source failures never masquerade as successful empty results.
Open More run actions beside Run now to run Run assessor or Run prioritizer separately. Run now remains the default action.
Run assessor, Run now and the opted-in schedule only assess tasks with no saved assessment history. Age, changed source state and edits do not automatically regenerate a saved judgment. Assess task and Assess selected explicitly create fresh versions when the work needs reassessment.
Run prioritizer refreshes tracked GitHub source state without collecting new tasks or calling the assessor, then orders the whole eligible list from saved judgments. Draft, CI, head revision and readiness are separate from permanent assessments. Current source state overrides historical readiness claims; unavailable or incomplete state stays unknown. Review-readiness demotion applies to review actions, not fixing your own PR's CI or advancing active work. Task details → Current PR status shows the last observation separately from assessment history. A failed refresh or missing assessment preserves the previous order. Separate agent runs never advance the collection cursor or schedule.
If no saved version matches the current assessor settings, prioritization can reuse the latest judgment and warns which tasks used earlier settings or a legacy format. Use Assess selected when you want new judgments. Pipeline runs reuse source observations already collected in that run instead of fetching the same status twice.
Assessment progress counts tasks only after their batch is saved. Its total includes only unassessed tasks, or the explicit selection when reassessing. Batches contain at most 20 tasks, so the bar advances in steps; large inputs can produce smaller batches. Cancel assessment interrupts the active request and stops remaining assessment and prioritization work. Already saved batches and the previous order remain; an unfinished model batch is discarded. A local save already underway finishes safely. Controls stay available in Settings, and the run stays busy until the active request and cancellation settle. After cancellation, Run assessor skips saved batches and continues with unassessed tasks.
The compact activity control beside Run now shows the current phase with a spinner that respects reduced motion. Click it for a non-modal Run details popover containing the profile, exact collection and assessment counts, progress bars, active source, elapsed time and supported cancellation. It starts closed and never moves the task list when opened. Escape or the close button returns focus to the control; clicking or tabbing outside dismisses it without blocking work. Phase changes and completion leave an open panel open. Failures and coverage notes remain labeled on the closed control. One collection is one enabled source, including its follow-up reads and saves; failed collections count as processed, not successful. These counts are not time estimates, and 100% collected does not mean the run has finished. Expand Coverage and run details for a keyboard-scrollable source checklist and diagnostics, without duplicating source warnings. Sources skipped after a storage failure are labeled Not run. The panel fits narrow windows; the checklist scrolls independently, with whole-panel scrolling only when the window is too short. Active progress and cancellation also stay visible in Settings. The completed checklist remains inspectable for the current session until the next run or profile switch; saved run errors and the last successful run time remain available after relaunch.
Choose Filters in the left menu to keep a source tree beside your tasks. Toggle an entire GitHub, Slack or MCP group, or individual configured sources. Manual tasks and external-agent intake have separate checkboxes. Tasks matching any checked source appear once, in the same order and with the same ranks as Ranked Tasks. Filtering applies to To do, Done and No action now; source counts follow the current tab and can overlap.
Selections and collapsed groups save automatically per work profile, including across relaunch and in backups. New profiles start with all sources selected. Select all / Show all sources also includes sources added later; a custom selection includes only the sources you checked. Selecting nothing shows an empty view, never deletes tasks. Disabled sources remain available for filtering saved tasks; removed sources use their saved source ID as a label. Tasks without saved provenance appear under Other saved tasks. Ranked Tasks always shows the full list. Filters do not change source collection, schedules, ranking, Done or notes. Ranked Tasks always shows the full list. Filters do not change source collection, schedules, ranking, Done or notes.
In Settings → Work styles, define names and descriptions for this profile. There are no required categories: Quick wins and Deep focus are examples, not defaults. The Task assessor assigns zero or more matching styles from task evidence. Complete definitions save automatically. For tasks with existing assessments, use Assess selected; changing definitions never automatically reruns an assessment.
Styles appear as pills on task rows. Filters → Work styles matches any selected style within the selected sources, preserving original ranks across To do, Done and No action now. All styles includes unclassified tasks. Filter choices persist per profile; Ranked Tasks bypasses both source and style filters.
In Task details → Why this order → Assessment → Work styles, change the style checkboxes to save your own assignments, including no styles. Reassessment never overwrites these corrections. Use Copilot assignments restores the latest saved automatic assignments. Renaming a style updates its current pills; deleting it hides them without deleting history. Historical assessments retain the original definitions, and details disclose changed definitions. The Implementation assessor remains a separate code-inspection agent.
Use Work profile in the sidebar footer, above Settings, to switch between named setups, such as regular work and on-call work. The row shows the active name; click it to open the profile list and Add profile. The popover leaves the task list in place, scrolls for long lists and explains when switching is temporarily unavailable. Escape closes it and returns focus; clicking or tabbing outside also dismisses it. Your existing setup becomes Default, without changing its tasks or settings. Add profile creates and selects an empty task list, then opens its settings. Optionally copy the current profile's saved instructions, sources and model; automatic runs start off. Rename the selected profile in Settings.
Each profile keeps its own agents, sources, collection model, schedule, tasks, notes, Done history, ranking and notification cursor. Older settings initialize both agents with the saved owner instructions and model; sources and scheduling stay unchanged. Agent edits thereafter are independent. Display-name changes retain the stable agent identity and do not invalidate judgments. The same source can appear independently in different profiles; completing it in one does not complete it in another. Switching waits until a run or unsubscribe finishes.
Work profiles → Export profile downloads the selected profile's configuration as a versioned JSON file: its name, agent instructions and models, work styles, sources and cadence. Tasks, notes, assessments, run history, filter selections, connections and credentials are not included. Instructions and source queries can contain private information; review the file before sharing it.
Import profile accepts that JSON file and lets you choose a unique name. It creates and selects a new profile, then opens Settings for review. Existing profiles remain unchanged; the imported task list starts empty and automatic runs start off, even if enabled in the exported configuration. Connect any required MCP servers separately. Invalid, unsupported or oversized files (over 2 MiB) show an error without changing the workspace.
Task details → Implementation assessor → Assess implementation inspects a GitHub issue and its pinned default-branch code. PR reviewer → Review PR inspects a PR at its pinned head and merge base. Both run inside this app and save results automatically. Configure the Implementation assessor and PR reviewer in the same Settings agent section. Existing assessor/prioritizer customizations stay unchanged. Each role has one stable identity, editable name/instructions/model, and fixed capabilities.
Code jobs run only after an explicit task or batch action, never from selection, focus, Run now or a schedule. They use only bounded list_code and read_code tools; task notes and private thread notes are excluded. They cannot execute or edit code, delegate, mark Done, or submit/approve a GitHub review. Notes, capture, Done, navigation and profile switching remain usable while a code job runs. Another Copilot run waits.
Use the checkboxes in To do to select tasks without opening details. Select visible tasks follows the current source filters; Clear selection changes no saved tasks. The count and contextual actions describe the selected scope. Selection for future starts stays local to this view and clears when the profile, tab, source filter, workspace or settings view changes. Done or removed tasks leave the selection. Opening another task's details does not change it or start network work. An already-started batch keeps its frozen task IDs across tabs, filters and Settings; its separate summary shows the original selection count.
Assess selected forces new task assessments only for those eligible IDs, using the same permanent history as Run assessor. Assess task in details does the same for one task. Neither collects sources nor changes order. Unavailable, removed or concurrently changed tasks are disclosed rather than replaced with other tasks. Changing the assessor's instructions or model stops remaining selected assessment requests; already-in-flight results are saved as history. If all selected work was already in flight, it finishes with a settings-change warning. Whole-list assessment keeps its existing behavior: finish with the original settings, then warn. Run prioritizer remains a separate whole-list action; there is no subset ordering presented as a global rank.
Assess implementation (N issues) and Review selected PRs (N) run only the named source kind. Expand Code eligibility to see which selected tasks cannot run each action. Unknown legacy source kinds stay unknown until explicit Run now collection. Code jobs run one at a time, with a reservation across the whole batch that blocks scheduled, whole-list and single-detail agent starts between tasks. IDs, source references, profile, workspace generation and agent policy are frozen; each dispatch rechecks eligibility. A completed task failure can continue to the next independent task. Interrupted/cancelled jobs, recovery, lost profile/policy, and failed starts or result saves stop the rest.
Stop batch, available in the task list, task details and Settings, immediately marks queued tasks Not started, requests cancellation of the current job, and waits for its actual outcome, not its cancel acknowledgement. Navigation and source filters do not stop or change a started batch. Changing profiles, restoring the workspace or saving changes to the running code agent's instructions/model still stops remaining jobs and requests cancellation. Notes, capture, Done and detail navigation remain available. Batch outcomes shows completed, not-inspected, failed, cancelled, skipped, not-started and unsaved results with per-task explanations. Completed means a saved partial inspection, not approval or implementation. Zero-read PR results count separately as Not inspected, never completed inspections. Retry or export an unsaved result in task details without rerunning the model.
The batch queue and summary are session-only and never resume automatically. Actual runs retain their permanent task history across relaunch; rerunning is always explicit.
Results show the original agent settings, inspected revisions, linked code evidence, findings, and an implementation next step where applicable. After successful code reads, Partial coverage means selective inspection, not comprehensive verification. A PR with no successful reads shows No code inspected and No code coverage obtained, not a completed review or selective inspection. Empty findings never imply approval. Results are historical after their displayed verification time; rerun explicitly to inspect current code. Any source/head/base movement during a run fails with a rerun message, including unrelated issue default-branch movement.
Every start intent is saved before network access. Each rerun appends a new version; details page through ten versions in append order. Cancellation waits for the target request's actual outcome. Database restore hides the previous task's run but keeps new Copilot work blocked until that request settles. Relaunch or restore never replays interrupted work. Once the request settles, pending result persistence does not block new Copilot work. A failed result save retains a visible result with Retry saving result and export; retrying saves the same result without another model call. Unsaved results must be retried or exported before quitting.
Code runs live in checksummed rows of the same SQLite database, outside the 8 MiB snapshot. Database backups and the actual 64 MiB JSON export include all runs. Late results from a replaced workspace are saved in a separate durable quarantine, never attached to restored tasks with matching IDs; Backups & recovery → Code results from previous workspaces reads/exports them. A failed quarantine write remains explicitly pending for retry/export.
Canonical task dedup still combines issue/PR URLs. Live collection retains GitHub's observed source kind separately. Legacy issue-form links without authoritative kind or matching pull evidence show Source kind unknown; use Run now to collect their source explicitly before starting a code job. No action name guesses the kind, and selection never fetches it.
External-agent intake goes into whichever profile runs next, and is acknowledged only after saving. Saved thread notes, connections, appearance and backups remain shared. Backups include every profile, and the selected profile survives relaunch.
Copilot saves importance, urgency, blockers, evidence and uncertainty alongside impact, visibility and effort ratings. Each rating is high, medium, low or unknown with a short rationale; missing implementation evidence is not an effort estimate. Only unassessed tasks automatically send full evidence, in batches of up to 20 tasks and 240,000 UTF-8 bytes. Each batch saves before the next starts. Content or assessor-setting changes remain visible as a reason to consider explicit reassessment, not a prerequisite for ranking.
Saved judgments do not expire. An older assessment's reevaluation suggestion remains historical provenance, not an automatic rerun or ordering gate. Comparative ordering can be reused for up to 1 hour, provided task inputs, observed PR state and prioritizer instructions are unchanged. A new draft/CI state invalidates ordering, not assessment history. Source checks still run; observation timestamps alone do not invalidate an otherwise identical order. The derived order cache remains credential-scoped, but native task history remains usable after cache loss or credential rotation.
Task details puts auto-saved task notes above a bounded Why this order area. Overview shows the ranking reason and latest impact, visibility, effort and work-style pills. Assessment contains the latest importance, urgency, blockers, expandable rating rationales, uncertainty, evidence, work-style corrections and Assess task. History is a separate audit view with the saved-version selector, older pages and provenance; selecting an old version never changes Overview or the latest Assessment. The tabs support arrow keys, Home and End. Evidence, evaluation time and provenance remain readable after edits, Done or relaunch. “Outdated” means saved inputs or settings changed; the judgment is still available for prioritization. Urgency and blockers are labeled as observations from assessment time, not fresh source checks. Blank model selection is identified as SDK default, not a guessed resolved model.
New v4 results include work-style assignments and the definitions used, alongside the agent and its configuration fingerprint. Earlier v2/v3 history stays readable; absent ratings and styles are labeled Not recorded, not invented. Changing an agent never rewrites its historical judgments. Roles and result formats are code-defined, with exactly one definition per supported role; instructions cannot grant tools, source access, delegation or GitHub writes.
Assessment history belongs to the task, including manual tasks, in separate rows of the same local SQLite database. Details read 20 versions at a time; Older assessments reads the next page. Logical append order identifies the latest result even if the clock moves backwards. Each subset saves before further assessment or ordering; retries do not duplicate versions. History does not count toward the 8 MiB task snapshot limit and never prunes itself.
Assessment save failures retain visible pending results with separate retry/export controls; notes, Done and capture can still save. Retry or export pending results before quitting. Database backups, raw preservation and restoration include all history. Backups & recovery also exports complete JSON copies up to 64 MiB; larger histories use database backups/raw preservation. Restoring an older database backup replaces its task state and history together, preserving the pre-restore database first. Results arriving from the previous workspace stay in a separate export-only quarantine with their original revision and generation; they never block new runs or attach to restored tasks. Export quarantined results before quitting. Old replaceable cache entries are not imported as history.
Each saved GitHub query collects up to 200 matches, using pages of 100. Larger or incomplete searches show a coverage warning; missing matches never mark tasks Done. Reply extraction batches source comments, and ranking still considers the whole active queue together.
Saved searches cache timelines and reply extraction across restarts. After a complete baseline, safe queries fetch issues updated since the saved scan boundary, with a five-minute overlap and full reconciliation every six hours. Every cached source still receives a live permission/state check, and PR checks and merge queues stay live. Later streams do not repeat tracked-only checks for sources already observed in the same run. Relative or complex queries keep full searches; failed or unsaved runs retain discoveries for replay.
Timeline gaps, unknown request ages and the 100-check limit remain visible as coverage notes, not failed reads that block a completed scan. Incomplete checks still prevent a PR from being declared ready to merge. Authentication and rate-limit failures stop the remaining reads in that GitHub operation; saved tasks remain intact.
A GitHub task identifies one issue or PR, using its normalized URL, not its action, notification or search result. Assignment, follow-up, reply and review requests for the same source join one task, including requests discovered through Slack or MCP. All requests share one Done state. Non-GitHub sources still identify source + action; manually captured tasks remain separate.
Existing duplicates combine when the workspace loads, after a durable backup of the original snapshot. The first task keeps its ID and title; other titles, notes, evidence and handled evidence are retained. If any duplicate is unfinished, the combined task stays open. Otherwise it stays Done, retaining the latest completion boundary (or no automatic reopening if any completed task lacks a boundary).
Done records handled evidence and a completion boundary. A repeated search, an old newly discovered message, or an unrelated comment cannot reopen it. A fresh actionable request with a new source event after completion can. Current merge-queue, closed and merged state removes tasks from To do without marking them Done; they remain in No action now.
In Settings, choose Add GitHub notifications. The source saves automatically and joins the same manual or scheduled run as saved searches. Use it instead of broad mentions searches; keep assigned-work, review-request and project backlog searches separately. Adding notifications does not rewrite or remove saved queries.
The first scan covers the last 30 days. Later scans include both read and unread issue/PR notifications updated since the last successful run. Reading a notification elsewhere does not finish a task. Large backlogs advance oldest-first across runs, with the remaining history shown in the task list. The saved cursor advances only through successfully inspected history, never beyond the run's start, after collection, ranking and persistence succeed. Failures retain the previous boundary for retry.
Notifications identify conversations to inspect, not obligations. Actual source requests determine the action and retain their original event IDs and occurrence times. Notification reasons can remain mention after unrelated activity, so neither the reason nor the notification's update time can reopen Done. Requests already found through another source join the same issue or PR task.
Unsubscribe on GitHub appears under the Conversation notifications disclosure in details for tasks discovered through notifications. Confirm it separately from Done. It stops following the conversation without closing the source, deleting the task or changing completion. Direct mentions, team mentions and review requests can still notify you again. The app saves the unsubscribe intent before sending it; unconfirmed writes stay visible for explicit retry and never replay automatically after relaunch.
Slack uses a selected existing MCP server and explicitly named read tools. Connection credentials stay backend-only. Choose Read MCP connections for the available shared configuration and setup instructions. A connection saved only in Copilot app settings is not automatically available to this separate SDK runtime.
New Slack sources prefill Allowed read tools with slack_search_public_and_private, slack_read_thread. Selecting Slack for a source with an empty tool list fills the same defaults. Saved settings and custom tool lists stay unchanged. Choose the server, review the tools and enable the source before saving; new sources start disabled.
Server and tool names must match exactly, including case. For public-only Slack searches, replace slack_search_public_and_private with slack_search_public. A configured wildcard does not approve all tools in this app; select the read tools explicitly.
Other apps can submit tasks through the packaged service's --mcp stdio entry. For a completed Copilot review, submit a review-result task with the PR URL, a stable event ID and the source event time. The producer must call the tool; installing the server does not itself install an automatic review-completion hook. Intake is durable even while the desktop is closed, and is acknowledged only after the task reaches the workspace's durable save.
See the service contract for source configuration, intake arguments, bounds and authentication. The app does not embed Slack credentials or silently reuse unrelated tools.
Ranked Tasks uses three panels: navigation, the ranked list and task details. Filters adds a locally filtered view of the same tasks with a scrollable, collapsible source tree. Settings replaces Appearance in the sidebar and includes themes, sources, priorities and scheduling. On narrow windows, task details replace the list until closed.
The old Inbox, Filtered, Archive, Tasks and saved-reference views are retired. Waiting on me and filtering rules are removed, including their logic. Source queries control discovery. Saved thread notes remain private and editable in a collapsed disclosure beside matching tasks; backups retain all notes and conversations. Task Details no longer renders the conversation reader or offers Load conversation or cache discard. Open source remains available; selecting a task neither reads nor fetches conversation bodies. Existing conversation caches are untouched. Existing saved filtering rules and named inboxes are retired only after an original backup succeeds.
Build prerequisites: macOS 12 or later, Xcode Command Line Tools, a Rust toolchain, and Bun 1.3.14. Install both locked dependency sets:
bun install --frozen-lockfile
(cd service && bun install --frozen-lockfile)
bun run native:devDevelopment uses 127.0.0.1:1420. bun run dev:desktop alone is only the renderer; it cannot read SQLite without Tauri.
For the standalone app:
bun run native:build
open "src-tauri/target/release/bundle/macos/GitHub Projects.app"The release profile preserves metadata in build-time dependencies to avoid Rust's E0463 procedural-macro errors on macOS. No environment override is needed.
To build and install into /Applications, quit any running copy first:
bun run install_app
open "/Applications/GitHub Projects.app"This replaces the installed app's bundle contents without touching local data. It requires write access to /Applications; it does not request administrator privileges.
The build compiles a target-specific standalone service and includes it inside the app. The app does not require Bun, Node, node_modules, or the repository at runtime. Apple Silicon and Intel service targets are supported; actual bundle/authentication validation ran on Apple Silicon.
The bundle is ad-hoc signed for local use, not notarized for distribution.
The app icon source is src-tauri/icons/source.png. Its PNG and ICNS variants are generated with Tauri's icon command.
Local capture, thread notes, task notes and Done work without authentication.
For GitHub, install gh and sign in with gh auth login --hostname github.com. The backend discovers CLIs through absolute PATH entries and standard install directories, including ~/.local/bin. It never exposes tokens to the renderer. Copilot App handoffs require Copilot App; checking the retained service's SDK connection additionally requires copilot and an account with access.
GitHub notifications require classic notifications or repo scope. Private source evidence needs repo; confirmed team membership needs read:org or its parent scopes. Organization access may also require SSO authorization. Unsupported authentication, absent CLIs, missing scopes, SDK failures, and partial source coverage are explicit errors, not demo fallbacks.
Use Connections → Check connections to check prerequisites. It does not fetch notifications. With scheduled runs disabled, startup, focus, navigation and reconnect do not call GitHub or the SDK. Enabled schedules explicitly opt into collection and ranking while the app is running.
The desktop starts empty after reading SQLite. It never opens browser storage, fixtures, or the previous app's database. Its identifier and data namespace are io.robertcrandall.github-projects-workspace:
~/Library/Application Support/io.robertcrandall.github-projects-workspace/
SQLite saves the checksummed, revisioned workspace atomically. Saved on this Mac appears only after the newest queued changes persist. Conflicts and failed saves retain pending work rather than overwriting another revision. Backups & recovery provides pending-copy export, preservation of database files, and explicitly confirmed backup recovery. Recovery never silently resets corrupt data.
Current version-2 data converts to version 3 after a durable immutable backup succeeds. Linked action notes become separate thread annotations with original titles/history. Explicit captured tasks stay tasks even when linked; their thread annotations appear in task details. Their new task notes start empty. Standalone actions/routines become tasks with preserved notes and history. Completed/removed tasks stay Done. No unrelated older application storage is inspected.
The migration retains capture text, progress, step timestamps, project/next-step text and routine history in saved records. The original backup also preserves the retired undo stack. Loading version 3 does not repeat the conversion.
Unconfirmed GitHub writes remain visible and explicitly retryable after relaunch. They never replay automatically. A timeout or interrupted process may follow a successful remote write; check GitHub or retry explicitly rather than treating it as success.
Conversation bodies live in a separate checksummed SQLite cache in the same private app directory, outside workspace snapshots and their 8 MiB limit. A source means one repository + issue/PR type + number, independent of notification IDs. Limits are 4 MiB per source and 64 MiB total, measured as serialized UTF-8 data; each service page holds at most five messages within 1 MiB. Untransportable pages and full/corrupt caches produce explicit errors, never shortened bodies, silent eviction or lost notes.
The conversation reader and its cache-discard controls are retired from Task Details. This layout change does not delete or migrate cached conversations, notes or backups. Use Open source to read the live conversation externally.
Legacy routines and native reminder delivery are retired. The native reminder array remains empty; the new collection cadence lives separately in task settings. A legacy snapshot cannot notify while loading, after a failed migration, or after backup recovery. Closing hides the existing window; Show GitHub Projects returns it and Quit GitHub Projects stops the owned service process group.
Both Vite entries render the same desktop workspace. They require native IPC for task storage; the separate synthetic browser prototype is retired. Browser tests provide mocked IPC without touching live data.
bun run test
bun run test:browser
bun run build
bun run build:desktop
bun run build:service
bun run test:native
(cd service && bun run typecheck && bun run build arm64 && bun test)
bun run native:build
codesign --verify --deep --strict \
"src-tauri/target/release/bundle/macos/GitHub Projects.app"The browser suite covers the unified workspace through both renderer entries with mocked Tauri IPC. If Chromium is missing, run bunx playwright install chromium. Tests never perform live GitHub writes or request reminder permission.
The packaged executable provides non-prompting native smoke checks:
app="$PWD/src-tauri/target/release/bundle/macos/GitHub Projects.app/Contents/MacOS/github-projects-workspace"
"$app" --native-smoke-check
session=$(uuidgen)
"$app" --native-ui-smoke-check --integration-smoke-session "$session"
"$app" --native-ui-smoke-relaunch --integration-smoke-session "$session"These use generated TEST directories, not app data. They check the ranked task home, persistent Done, and scheduled ranking while the window is hidden. An explicit smoke-only service fixture supplies responses; unexpected service/model operations fail instead of reaching GitHub. The relaunch command removes that test session; a standalone UI smoke without a session flag cleans up after itself. Smoke failures exit nonzero.
--integration-service-smoke-check explicitly performs a tiny synthetic SDK inference and a bounded read-only GitHub refresh through the packaged native host. It consumes Copilot service access and must not run as an automatic test. --integration-read-smoke-check performs only the read-only refresh. Both use private TEST directories and report counts/status, never source bodies or tokens.
- PRODUCT.md defines behavior; DESIGN.md and theme.md define the approved interface.
- Native integration contract documents SQLite revisions, recovery, retired schedules, destinations, and owned process hosting.
- Service contract documents auth, exact endpoints, source coverage, SDK isolation, and bounded JSONL transport.
GitHub refresh is a bounded view of notifications and REST timeline evidence, not full repository synchronization. Missing notifications prove nothing. Archive retains a monotonic source timestamp; without a notification baseline, activity must be newer than the local archive time. A newly discovered same-timestamp ID alone cannot prove new activity. The retained conversation infrastructure supports REST message pages, not every historical revision, file diff, resolved-review status or repository content. The service is capability-restricted but not an operating-system sandbox. External Copilot App launching is separate from SDK previews.