Skip to content

Implement Incoming Jumps feature end-to-end#185

Merged
mikkisguy merged 6 commits into
mainfrom
175-write-mode-add-incoming-jumps-section
Jun 3, 2026
Merged

Implement Incoming Jumps feature end-to-end#185
mikkisguy merged 6 commits into
mainfrom
175-write-mode-add-incoming-jumps-section

Conversation

@mikkisguy

@mikkisguy mikkisguy commented Jun 3, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added "Incoming Jumps" collapsible section in Label Properties Panel showing labels that jump to the current label (source, jump type, choice/automatic, and conditions)
    • Enhanced "Outgoing Jumps" display with counts, per-jump details, type badges, condition flags, and stat-effect annotations
    • Public label data now optionally includes incoming jumps for use by the UI
  • Documentation

    • Added design specification for the incoming jumps feature

mikkisguy added 4 commits June 3, 2026 09:23
- Implement updateIncomingJumpsForLabel service function
- Integrate into syncLabelsInTransaction
- Add Incoming Jumps section to LabelPropertiesPanel
- Show count badge, source labels, choice text, and conditions
- Design and implementation plan docs
@mikkisguy mikkisguy self-assigned this Jun 3, 2026
@mikkisguy mikkisguy linked an issue Jun 3, 2026 that may be closed by this pull request
5 tasks
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@mikkisguy, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 56 minutes and 34 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 492e530c-5b7b-4450-8360-4e36e22c4a8b

📥 Commits

Reviewing files that changed from the base of the PR and between 4d66bcc and c113d9a.

📒 Files selected for processing (1)
  • .changeset/sharp-ties-throw.md
📝 Walkthrough

Walkthrough

Adds persistent IncomingJump metadata and UI: shared type, DB migration and schema, backend batched recompute and UUID-aware resolution integrated into label sync, seed updates to populate test data, and frontend incoming/outgoing jump panels.

Changes

Incoming Jumps Feature

Layer / File(s) Summary
Shared Type Contract: IncomingJump and PublicLabel Extension
packages/shared/src/index.ts
IncomingJump interface added and `PublicLabel.incomingJumps?: IncomingJump[]
Database Schema and Migration for Incoming Jumps
apps/backend/src/db/migrations/0042_right_fabian_cortez.sql, apps/backend/src/db/migrations/meta/_journal.json, apps/backend/src/db/schema/tables/labels.ts
Adds incoming_jumps JSONB column to labels table and wires it into the Drizzle schema with type `IncomingJump[]
Backend: Compute, Resolve, and Expose Incoming Jumps
apps/backend/src/services/labels.service.ts
Integrates recompute into syncLabelsInTransaction, adds updateIncomingJumpsForLabels (single-pass scan of non-deleted label lines, name→id resolution with UUID passthrough, deduping), updates labels.incomingJumps, updates resolveJumpTargets to preserve UUID-like targets, and exposes incomingJumps in LabelForPublic, listLabels, and mapToPublicLabel.
Frontend UI: Outgoing and Incoming Jumps Panel
apps/frontend/src/components/write-mode/LabelPropertiesPanel.tsx
Adds memoized outgoingJumps from activeLabel.lines, replaces prior outgoing display with collapsible "Outgoing Jumps" and "Incoming Jumps" sections rendering computed outgoing and persisted incoming jump metadata (types, choice text, conditions, stat effects).
Seed Script Updates and Design Documentation
apps/backend/scripts/seed-technical-badges.ts, docs/superpowers/specs/2026-06-02-incoming-jumps-design.md
Seed script creates/uses routeConfigs (tech_test), sets label route, and writes incomingJumps on target labels; design doc specifies schema, backend algorithm, UI, edge cases, and acceptance criteria.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

🐰
I nibble lines and count each hop,
From choice and jump the pathways stop—
Incoming trails I trace and cheer,
So every label knows who's near. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title Check ✅ Passed Title check skipped as CodeRabbit has written the PR title.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 175-write-mode-add-incoming-jumps-section

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot changed the title @coderabbitai Implement Incoming Jumps feature end-to-end Jun 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
docs/superpowers/specs/2026-06-02-incoming-jumps-design.md (1)

62-98: 💤 Low value

Minor doc drift vs. the shipped implementation.

A few details in this draft don't match what landed and could mislead future readers:

  • Line 65: the function is implemented as the batch updateIncomingJumpsForLabels(context, labelIds, projectId), not a per-label updateIncomingJumpsForLabel.
  • Line 98: the shared type/DB field is incomingJumps (camelCase), not incoming_jumps.

Optionally update or add a "as-built" note. Fine to defer since this is a dated design spec.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/specs/2026-06-02-incoming-jumps-design.md` around lines 62 -
98, Update the spec to match the shipped implementation: replace references to
the per-label function `updateIncomingJumpsForLabel(tx, labelId, projectId)`
with the actual batch function `updateIncomingJumpsForLabels(context, labelIds,
projectId)` (use the exact symbol `updateIncomingJumpsForLabels`) and change the
documented shared/DB field `incoming_jumps` to the camelCase `incomingJumps` as
implemented on `PublicLabel`; optionally add an "as-built" note summarizing
these two diffs so readers aren't misled by the dated draft.
apps/backend/scripts/seed-technical-badges.ts (1)

733-754: 💤 Low value

Fabricated automatic jumps don't correspond to real jump lines.

The extra AUTOMATIC entries derived from label_gold/label_gem/label_nothing claim those labels jump to chapter_two_scene_one, but none of the seeded label lines contain such jumps (only the main label's Line 5 does). This diverges from what updateIncomingJumpsForLabels would actually compute, so the seeded display won't match a real sync. Acceptable if the intent is purely to exercise multi-source rendering, but consider a brief comment so future readers don't treat it as representative.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/backend/scripts/seed-technical-badges.ts` around lines 733 - 754, The
seeded extra AUTOMATIC entries in the chapter_two_scene_one array (created from
label_gold/label_gem/label_nothing) do not reflect real jump lines and will
diverge from what updateIncomingJumpsForLabels computes; either remove these
fabricated entries or add a clear inline comment next to the
chapter_two_scene_one construction explaining they are artificial test-only
multi-source rendering fixtures (and not representative of real incoming jumps),
referencing the createdTargetLabels/map logic and the label names (label_gold,
label_gem, label_nothing) so future readers know why they are present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/backend/src/services/labels.service.ts`:
- Around line 2533-2540: The code collects menu option targets into targetNames
and then resolves them via labels.labelName, which causes UUID-like
targetLabelId values to fail resolution and be dropped; update the logic around
targetLabelId (used in the allLines loop and where incoming jumps are computed)
to preserve raw UUID targets: when a targetLabelId is present, if it is not
resolvable via labels.labelName (or matches a UUID pattern) treat it as a direct
label ID and add the raw targetLabelId to targetNames and to the incoming-jumps
mapping (incomingJumps/incomingMenuJumps) instead of attempting to look it up by
name; ensure subsequent comparisons handle both resolved label names and raw IDs
so incoming menu jumps referencing UUIDs are not dropped.
- Around line 991-993: The recompute step currently calls
updateIncomingJumpsForLabels(tx, affectedLabelIds, projectId) which restricts
incoming-jump recalculation to only affectedLabelIds; you must expand the scope
to include any labels that are jump targets referenced by the changed/synced
files (or all project labels if target discovery isn’t available). Modify the
code that builds affectedLabelIds and the call-site for
updateIncomingJumpsForLabels to compute a union: affectedLabelIds ∪
referencedTargetLabelIdsForFiles(projectId, changedFileIds), then pass that full
set into updateIncomingJumpsForLabels(tx, expandedLabelIds, projectId); also
update the places that filter writes to only affectedLabelIds (the write/filter
logic that checks membership) to use expandedLabelIds so incomingJumps for
cross-file targets are updated too.

In `@apps/frontend/src/components/write-mode/LabelPropertiesPanel.tsx`:
- Around line 116-126: The loop that builds the jumps array is including menu
options even when they don't actually jump; modify the logic in the block that
iterates line.menuOptions so you only push entries for options with a real jump
target (e.g., check opt.targetLabelId or another definitive target field before
creating the jump object). Update the code that pushes into jumps (the object
with targetLabelId, targetLabelName, jumpType, choiceText, conditionFlags,
effects) to be guarded by this truthy-target check so outgoingJumps no longer
counts non-jumping menu rows.
- Around line 523-525: The UI renders jump.choiceText directly but
IncomingJump.choiceText is nullable, causing empty labels; update the rendering
in LabelPropertiesPanel (where jump.choiceText is used) to provide a safe
fallback when null/empty (e.g., use a default string like "Untitled choice" or
localized fallback via i18n) so the row always shows a visible label; locate the
span that displays jump.choiceText and replace the direct value with a
nullish/empty check and the chosen fallback.

---

Nitpick comments:
In `@apps/backend/scripts/seed-technical-badges.ts`:
- Around line 733-754: The seeded extra AUTOMATIC entries in the
chapter_two_scene_one array (created from label_gold/label_gem/label_nothing) do
not reflect real jump lines and will diverge from what
updateIncomingJumpsForLabels computes; either remove these fabricated entries or
add a clear inline comment next to the chapter_two_scene_one construction
explaining they are artificial test-only multi-source rendering fixtures (and
not representative of real incoming jumps), referencing the
createdTargetLabels/map logic and the label names (label_gold, label_gem,
label_nothing) so future readers know why they are present.

In `@docs/superpowers/specs/2026-06-02-incoming-jumps-design.md`:
- Around line 62-98: Update the spec to match the shipped implementation:
replace references to the per-label function `updateIncomingJumpsForLabel(tx,
labelId, projectId)` with the actual batch function
`updateIncomingJumpsForLabels(context, labelIds, projectId)` (use the exact
symbol `updateIncomingJumpsForLabels`) and change the documented shared/DB field
`incoming_jumps` to the camelCase `incomingJumps` as implemented on
`PublicLabel`; optionally add an "as-built" note summarizing these two diffs so
readers aren't misled by the dated draft.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cc056114-f4de-402f-9a55-79a465c2e0d6

📥 Commits

Reviewing files that changed from the base of the PR and between 0f526fe and fdcc3a7.

📒 Files selected for processing (9)
  • apps/backend/scripts/seed-technical-badges.ts
  • apps/backend/src/db/migrations/0042_right_fabian_cortez.sql
  • apps/backend/src/db/migrations/meta/0042_snapshot.json
  • apps/backend/src/db/migrations/meta/_journal.json
  • apps/backend/src/db/schema/tables/labels.ts
  • apps/backend/src/services/labels.service.ts
  • apps/frontend/src/components/write-mode/LabelPropertiesPanel.tsx
  • docs/superpowers/specs/2026-06-02-incoming-jumps-design.md
  • packages/shared/src/index.ts

Comment thread apps/backend/src/services/labels.service.ts Outdated
Comment thread apps/backend/src/services/labels.service.ts Outdated
Comment thread apps/frontend/src/components/write-mode/LabelPropertiesPanel.tsx
Comment thread apps/frontend/src/components/write-mode/LabelPropertiesPanel.tsx
@mikkisguy mikkisguy merged commit ea77c58 into main Jun 3, 2026
5 checks passed
@mikkisguy mikkisguy deleted the 175-write-mode-add-incoming-jumps-section branch June 3, 2026 18:17
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.

Write Mode: Add 'Incoming Jumps' section to LabelPropertiesPanel

1 participant