Skip to content

feat(apps): show UI extensions and install URL in apps view#377

Merged
scottlovegrove merged 2 commits into
mainfrom
feat/apps-view-ui-extensions
Jun 2, 2026
Merged

feat(apps): show UI extensions and install URL in apps view#377
scottlovegrove merged 2 commits into
mainfrom
feat/apps-view-ui-extensions

Conversation

@scottlovegrove

Copy link
Copy Markdown
Collaborator

What

Expand td apps view <ref> so that when an integration ships UI extensions, the view:

  • Lists each UI extension as <name> (<type>[: <sub-type>]), where type is context-menu / composer / settings and sub-type is the context-menu context (project/task) or composer location (task/comment). Settings extensions have no sub-type.
  • Prints the installable URL (https://app.todoist.com/app/install/<distribution_token>) — the link an integration owner shares so others can install it. This is required for any integration with UI extensions.

When an app has no UI extensions, neither the section nor the install URL is shown.

Why

The view previously omitted the install URL entirely, which is required to distribute an integration that has UI extensions. The SDK already exposes getUiExtensionsForApp (previously unused) to detect them; the install URL mirrors how todoist-web builds it (<origin>/app/install/<distribution_token>).

Distribution token reclassified as non-secret

The distribution token is the basis of a shareable install link by design, so it is now:

  • always fetched (no longer gated behind --include-secrets)
  • surfaced via the Install URL line / installUrl JSON field by default

The genuinely sensitive credentials — client secret, verification token, test token — remain hidden by default.

Output

--json / --ndjson now always carry uiExtensions, distributionToken, and installUrl (null when the app has no UI extensions).

Testing

  • npm run type-check
  • Full suite: 1686 tests ✅ (new tests cover with/without UI extensions, sub-type formatting, and JSON payload)
  • npm run check (lint + format) ✅
  • Skill content updated + npm run sync:skill

Expand `td apps view <ref>` so that when an integration ships UI
extensions, the view lists each extension (name + type and variant
sub-type, e.g. `context-menu: project`, `composer: task`, `settings`)
and prints the installable URL
(`https://app.todoist.com/app/install/<distribution_token>`) — the link
shared so others can install the integration.

The distribution token is reclassified as non-secret (it is the basis of
a shareable install link by design): it is now always fetched and the
install URL is shown by default, no longer gated behind
`--include-secrets`. The genuinely sensitive credentials (client secret,
verification token, test token) stay hidden by default.

`--json` / `--ndjson` now always carry `uiExtensions`, `distributionToken`,
and `installUrl` (null when the app has no UI extensions).
@scottlovegrove scottlovegrove self-assigned this Jun 2, 2026
@doistbot doistbot requested a review from henningmu June 2, 2026 09:45

@doistbot doistbot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks Scott for surfacing UI extensions and shareable install links in the apps view 😎 👊.

Few things worth tightening:

  • Register getUiExtensionsForApp in API_SPINNER_MESSAGES and METHOD_REQUIRED_FLAG within src/lib/api/core.ts to ensure API errors are formatted correctly and missing permissions prompt for the app-management scope.
  • Defer fetching the distribution token in the default plain-text flow until after confirming the app has UI extensions to avoid an unnecessary API call.

I also included a few optional follow-up notes in the details below.

Optional follow-up notes (3)
  • [P3] src/commands/apps/view.ts:28: The default branch drops exhaustiveness on the SDK’s UiExtension discriminated union. If a new extension type is added upstream, this helper will keep compiling and silently render a partial label instead of forcing us to handle the new shape. Prefer explicit branches for the current variants plus a never fallback so SDK additions fail at compile time.
  • [P3] src/lib/skills/content.ts:354: This description now overstates the plain-output behavior. view.ts only renders the install link when the app has UI extensions, but this says the distribution token is "always shown." Since SKILL_CONTENT is the source of truth for agents, tighten the wording to distinguish plain output (install URL only when UI extensions exist) from JSON, where distributionToken is always present.
  • [P3] src/commands/apps/apps.test.ts:551: This fixture hand-builds the full SDK UiExtension shape even though these tests only assert name, extensionType, and the subtype field. That makes the suite noisy and brittle to unrelated SDK field changes. A small local makeUiExtension(...) helper (or shared fixture if you want to reuse it) would keep each case focused on just the fields under test.

Share FeedbackReview Logs

Comment thread src/commands/apps/view.ts Outdated
Comment thread src/commands/apps/view.ts Outdated
- Register getUiExtensionsForApp in API_SPINNER_MESSAGES and
  METHOD_REQUIRED_FLAG (core.ts) so its errors get CliError formatting
  and a 403 prompts for the app-management scope.
- Defer the distribution-token fetch: only call it when the app has UI
  extensions (plain output) or for --json/--ndjson, avoiding an
  unnecessary round-trip in the common no-extensions path.
- Make formatExtensionType exhaustive over the UiExtension union with a
  never fallback so new SDK variants fail at compile time.
- Tighten SKILL_CONTENT wording: install URL appears in plain output only
  when UI extensions exist; distributionToken is always present in JSON.
- Refactor test fixtures behind a makeUiExtension helper.
@scottlovegrove scottlovegrove added the 👀 Show PR PR must be reviewed before or after merging label Jun 2, 2026
@scottlovegrove scottlovegrove merged commit 53d9fe6 into main Jun 2, 2026
5 checks passed
@scottlovegrove scottlovegrove deleted the feat/apps-view-ui-extensions branch June 2, 2026 10:03
doist-release-bot Bot added a commit that referenced this pull request Jun 2, 2026
## [1.72.0](v1.71.0...v1.72.0) (2026-06-02)

### Features

* **apps:** show UI extensions and install URL in `apps view` ([#377](#377)) ([53d9fe6](53d9fe6))
@doist-release-bot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.72.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@henningmu henningmu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released 👀 Show PR PR must be reviewed before or after merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants