Skip to content

fix(ui-12b): push modal surfaces karasu watch inline (VAPID-null)#123

Merged
VDP89 merged 1 commit into
mainfrom
fix/ui-12b-push-modal-vapid-cli-hint
May 16, 2026
Merged

fix(ui-12b): push modal surfaces karasu watch inline (VAPID-null)#123
VDP89 merged 1 commit into
mainfrom
fix/ui-12b-push-modal-vapid-cli-hint

Conversation

@VDP89
Copy link
Copy Markdown
Owner

@VDP89 VDP89 commented May 16, 2026

Summary

Fix

src/karasu/ui/static/js/push.js line 193-195:

Before:

footCopy.textContent =
    'VAPID keys not provisioned. See docs/local-dogfood.md ' +
    'for manual setup.';

After:

footCopy.textContent =
    'VAPID keys not provisioned. Run `karasu watch` in a ' +
    'terminal once to bootstrap.';

Invariants preserved

  • Pin §11.6.14: the primary "Enable notifications" button stays DISABLED in this state. The chip change does not enable any new mutation path.
  • Notification.requestPermission and PushManager.subscribe remain unreachable from VAPID-null.
  • The defensive setPushModalError('VAPID keys not provisioned.') guard at push.js:250 (race-against-stale-payload path) is untouched and stays terse.

Files

  • src/karasu/ui/static/js/push.js — foot copy + extended comment linking the change to the dogfood finding.
  • tests/test_ui_sw.py::test_push_modal_vapid_null_foot_copy_surfaces_cli_hint — new static text pin in the existing "UI artefact source-level checks" pattern. Asserts the inline karasu watch hint is present + guards against reintroducing the old doc pointer.
  • docs/ui/ui-12b-design-brief.md — §3-H amended in-place to seal the new operator-actionable copy and document the regression risk.

What's NOT in this PR

  • No dogfood log touch (sub-friction 3 lives in PR docs: VAPID bootstrap consolidation — closes Finding #3 (sub-frictions 1 & 2) #118's resolution block, not on main). Follow-up housekeeping after both merge.
  • No Playwright test for the modal-rendered copy. The 4 existing Playwright flows in test_ui_push_modal.py cover the subscribe/unsubscribe contracts; the foot-copy assertion lives at the source level, matching the test_login_html_* and test_index_html_* pattern already established in test_ui_sw.py.

Test plan

  • pytest tests/test_ui_sw.py — 18/18
  • pytest tests/test_ui_push_modal.py tests/test_ui_modal.py — 13/13 (no flow regression)
  • After merge: an operator running karasu ui without karasu watch and opening the push modal from the standalone PWA window should see the karasu watch hint inline and be able to copy it without switching to a browser tab.

Relation to other Phase 4 PRs

Independent of #116-#122. The new test only reads push.js source; no other surface touched.

🤖 Generated with Claude Code

Closes phase-4-dogfood Finding #3 sub-friction 3 (logged in
PR #118's resolution): the UI-12b push modal's VAPID-null foot
copy used to read "VAPID keys not provisioned. See
docs/local-dogfood.md for manual setup." That works at a
terminal but FAILS in the operator's standalone PWA window
(installed via UI-14) where there is no terminal handy, no
clickable doc link, and the chip text is the operator's only
context.

Fix: replace the doc-pointer with the runnable CLI command
inline. New foot copy reads "VAPID keys not provisioned. Run
`karasu watch` in a terminal once to bootstrap." The command
goes IN the chip so the operator can copy + paste it directly
without leaving the window. The watcher's auto-provisioning
discipline (UI-12c §3-G + local-dogfood §First-start) is
unchanged; only the in-PWA hint shape moves.

Pin §11.6.14 carry-forward: the primary button stays DISABLED
in the VAPID-null state, so this change only touches the foot
copy. The defensive setPushModalError('VAPID keys not
provisioned.') guard later in the file (line 250) is untouched
— it covers a separate race-against-stale-payload path and
should stay terse.

Brief §3-H amended in-place to seal the new operator-actionable
copy and document the regression risk.

Tests:

- tests/test_ui_sw.py::test_push_modal_vapid_null_foot_copy_surfaces_cli_hint
  — parses push.js and asserts the inline `karasu watch`
  hint is present, plus a guard that the old
  "See docs/local-dogfood.md" pointer was not reintroduced.

Test surfaces touched: 18/18 in test_ui_sw.py, 13/13 across
test_ui_push_modal + test_ui_modal. No code paths exercised
by the Playwright modal flows changed shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 326b63e3e4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

footCopy.textContent =
'VAPID keys not provisioned. See docs/local-dogfood.md ' +
'for manual setup.';
'VAPID keys not provisioned. Run `karasu watch` in a ' +
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Make the CLI hint pasteable as shell input

When the modal is shown in the VAPID-null state, the visible text now includes literal backticks around karasu watch. If an operator follows the new copy/paste workflow and pastes that visible command including the backticks into a POSIX shell, the shell treats it as command substitution rather than running karasu watch normally, which can hang or fail instead of bootstrapping VAPID. Since this change is specifically meant to make the modal copy actionable, render the pasteable command without shell metacharacters or style it separately while keeping the copied text as karasu watch.

Useful? React with 👍 / 👎.

@VDP89 VDP89 merged commit dbde0e9 into main May 16, 2026
2 checks passed
@VDP89 VDP89 deleted the fix/ui-12b-push-modal-vapid-cli-hint branch May 16, 2026 13:54
VDP89 added a commit that referenced this pull request May 16, 2026
Reconciles the cross-PR references that the individual fix
PRs could not touch because they branched off main while the
hygiene items only existed in PR #116's resolution block.

Updates:

- Hygiene #5(a) (login chip text per status) marked resolved
  by PR #122.
- Hygiene #5(b) (`!unknown:` sentinel for direct loopback)
  marked resolved by PR #121.
- Finding #3 sub-friction 3 (modal does not surface CLI
  command) marked resolved by PR #123.

The "Outstanding sprint items" section is rewritten as
"Sprint items closed 2026-05-16" — an audit trail of the
five items addressed in one session, each linked to its
landing PR. Adjacent housekeeping (the Karasu- → Karasu
rename + PR #120 reference cleanup) is also captured for
the historical record.

Final line marks path C VPS deploy as unblocked at the code
surface; remaining gate is operational (domain + VPS +
caddy/Let's Encrypt per docs/deploy-runbook.md).

Pure docs change — no code, no tests, no brief touched.

Co-authored-by: Victor Del Puerto <VDP89@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant