Skip to content
This repository was archived by the owner on Nov 10, 2026. It is now read-only.

Allow distribution-only protocol handlers in Apple bundles - #747

Merged
daehyeon-mun merged 1 commit into
mainfrom
daehyeon/t3-fw-distribution-handlers
Oct 18, 2026
Merged

daehyeon-mun merged 1 commit into
mainfrom
daehyeon/t3-fw-distribution-handlers

Conversation

@daehyeon-mun

Copy link
Copy Markdown
Collaborator

Apps can mark a protocol handler distribution_only: true to register it only in Apple archives and explicit --distribution builds. Development bundles omit that entry from both CFBundleURLTypes and ExactProtocolHandlers, so lane builds can exercise link parsing without claiming the installed app's URL scheme.

The existing archive/distribution fact reaches every macOS and iOS plist assembly path. Ordinary handlers retain their behavior. Build-only flags are stripped from native handler dictionaries, which Swift reads as [[String: String]]. The option participates in native binary identity; web-manifest copying is unchanged. Includes author examples and the routing contract update.

Verified with Bun 1.4.2: 34 manifest/Apple/build-stamp tests passed, caps passed all 8 categories, boot passed, and whitespace checks passed. Independent read-only review by the terminal lane found no issues. Tests generate both platform plists, check both registration keys, preserve normal and development schemes, reject malformed flag values, and verify the flag changes native metadata. A signed app/archive was not rebuilt for this build-metadata-only change.

Approved design: packaged-only T3 Code links. Framework PR targets main; app adoption follows after merge.

@daehyeon-mun
daehyeon-mun merged commit 2e17aaf into main Oct 18, 2026
2 checks passed
daehyeon-mun added a commit that referenced this pull request Oct 18, 2026
Prompt links now open a draft in T3 Code. A plain prompt opens No
project; repository and pull request links find the matching project or
existing thread across connected environments. Hidden characters are
removed with a persistent warning, existing drafts require Replace
draft, and a new pull request worktree requires Check out before any
setup script runs. Links never send messages automatically.

The palette offers Copy prompt link and Copy prompt link with repo and
model; user messages have a Copy prompt link action. Packaged builds
declare `t3code` with `distribution_only: true` and `/open?u=%s`, using
the separately adopted framework support. Development and lane bundles
register no scheme. Lane verification enters the app route directly.

Ported upstream `5fe7568e87` (pingdotgg/t3code#18454), matching
reference `9c161462c9`. Shared parsing, hidden-character rules,
repository/model selection, draft replacement text and checkout choices
follow the upstream implementation; the app reuses its existing
connection fleet, project cloning and PR preparation operations.

| Acceptance | Result | Proof |
| --- | --- | --- |
| Plain, repository and thread links prepare an unsent draft | Native
plain-link drive passed; repository/thread routing regressions pass |
[Unsent
draft](https://github.com/user-attachments/assets/1dce9208-35cb-4bfe-9b87-739f025baac8),
[tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links)
|
| Hidden characters and existing drafts | Native drive asserted exact
sanitized text and empty thread ID; warning/replacement tests pass |
[Draft
pair](https://github.com/user-attachments/assets/1dce9208-35cb-4bfe-9b87-739f025baac8),
[tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links)
|
| Existing PR thread and explicit new PR checkout | Handler tests pass;
no preparation before confirmation | [Handler
tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links/prompt-link-handler.test.ts)
|
| Missing repository clone / No project choices | Native choices render
above empty-home landing; clone requires explicit action | [Repository
pair](https://github.com/user-attachments/assets/d01161ad-d3b3-4e19-a440-33db43c2d852)
|
| Copy links from palette and user messages | Native-clipboard adapter
tests pass | [Copy
tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links/prompt-link-model.test.ts)
|
| Packaged-only handler, no lane scheme | Approved declaration; final
Info.plist has neither handler nor URL scheme | Manifest and final
native bundle inspection |


Native qualification at `c5f5ed247`; final source merges integration
`de2558b58b` (including #754) at `673945745`:

- Full Bun suite: **5,120 passed, zero failures, 123,043 assertions
across 356 files**. The focused prompt tests: 26 passed, 111 assertions.
- Frozen install, generator, strict app TypeScript, full optimized
Contract preflight (32.6 MB plan), caps and boot passed.
- Final native bundle passed. Its Info.plist contains neither
`CFBundleURLTypes` nor `ExactProtocolHandlers`.
- After integrating the current target: 763 affected tests passed (3,250
assertions across 34 files), strict TypeScript, full Contract preflight
(35,525,218 bytes), caps and whitespace checks passed. No new native
bake was needed for that app-task merge; final combined native
qualification follows integration.
- Matched native before/after captures passed, including
missing-repository choices above the landing and a sanitized, unsent
draft. Both fixtures use isolated lane homes and an explicit Git ceiling
so the real server offers its scratch workspace. No OS scheme is
registered or invoked.

![Incoming repository link before and
after](https://github.com/user-attachments/assets/d01161ad-d3b3-4e19-a440-33db43c2d852)

![Sanitized unsent draft before and
after](https://github.com/user-attachments/assets/1dce9208-35cb-4bfe-9b87-739f025baac8)

Known differences: none identified in the scoped behavior. The
scheme-registration framework change was reviewed separately in #747 and
is already adopted by the target branch; this PR changes app files only.

Prepared with Codex; continues work begun in the prior Claude session.

---------

Co-authored-by: Codex <noreply@openai.com>
expo-tuft Bot pushed a commit that referenced this pull request Oct 28, 2026
Prompt links now open a draft in T3 Code. A plain prompt opens No
project; repository and pull request links find the matching project or
existing thread across connected environments. Hidden characters are
removed with a persistent warning, existing drafts require Replace
draft, and a new pull request worktree requires Check out before any
setup script runs. Links never send messages automatically.

The palette offers Copy prompt link and Copy prompt link with repo and
model; user messages have a Copy prompt link action. Packaged builds
declare `t3code` with `distribution_only: true` and `/open?u=%s`, using
the separately adopted framework support. Development and lane bundles
register no scheme. Lane verification enters the app route directly.

Ported upstream `5fe7568e87` (pingdotgg/t3code#18454), matching
reference `9c161462c9`. Shared parsing, hidden-character rules,
repository/model selection, draft replacement text and checkout choices
follow the upstream implementation; the app reuses its existing
connection fleet, project cloning and PR preparation operations.

| Acceptance | Result | Proof |
| --- | --- | --- |
| Plain, repository and thread links prepare an unsent draft | Native
plain-link drive passed; repository/thread routing regressions pass |
[Unsent
draft](https://github.com/user-attachments/assets/1dce9208-35cb-4bfe-9b87-739f025baac8),
[tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links)
|
| Hidden characters and existing drafts | Native drive asserted exact
sanitized text and empty thread ID; warning/replacement tests pass |
[Draft
pair](https://github.com/user-attachments/assets/1dce9208-35cb-4bfe-9b87-739f025baac8),
[tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links)
|
| Existing PR thread and explicit new PR checkout | Handler tests pass;
no preparation before confirmation | [Handler
tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links/prompt-link-handler.test.ts)
|
| Missing repository clone / No project choices | Native choices render
above empty-home landing; clone requires explicit action | [Repository
pair](https://github.com/user-attachments/assets/d01161ad-d3b3-4e19-a440-33db43c2d852)
|
| Copy links from palette and user messages | Native-clipboard adapter
tests pass | [Copy
tests](https://github.com/ccheever/exact2/tree/c5f5ed247bb39f050264c1f2faed5ddbc3c99556/examples/t3-code/tests/prompt-links/prompt-link-model.test.ts)
|
| Packaged-only handler, no lane scheme | Approved declaration; final
Info.plist has neither handler nor URL scheme | Manifest and final
native bundle inspection |


Native qualification at `c5f5ed247`; final source merges integration
`c7b9c3d746` (including #754) at `673945745`:

- Full Bun suite: **5,120 passed, zero failures, 123,043 assertions
across 356 files**. The focused prompt tests: 26 passed, 111 assertions.
- Frozen install, generator, strict app TypeScript, full optimized
Contract preflight (32.6 MB plan), caps and boot passed.
- Final native bundle passed. Its Info.plist contains neither
`CFBundleURLTypes` nor `ExactProtocolHandlers`.
- After integrating the current target: 763 affected tests passed (3,250
assertions across 34 files), strict TypeScript, full Contract preflight
(35,525,218 bytes), caps and whitespace checks passed. No new native
bake was needed for that app-task merge; final combined native
qualification follows integration.
- Matched native before/after captures passed, including
missing-repository choices above the landing and a sanitized, unsent
draft. Both fixtures use isolated lane homes and an explicit Git ceiling
so the real server offers its scratch workspace. No OS scheme is
registered or invoked.

![Incoming repository link before and
after](https://github.com/user-attachments/assets/d01161ad-d3b3-4e19-a440-33db43c2d852)

![Sanitized unsent draft before and
after](https://github.com/user-attachments/assets/1dce9208-35cb-4bfe-9b87-739f025baac8)

Known differences: none identified in the scoped behavior. The
scheme-registration framework change was reviewed separately in #747 and
is already adopted by the target branch; this PR changes app files only.

Prepared with Codex; continues work begun in the prior Claude session.

---------

Co-authored-by: Codex <noreply@openai.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant