Desktop: Phase 3 (step 3) broker serves /api/pending - #72
Conversation
📝 WalkthroughWalkthroughAdds a ChangesPending store reader and broker endpoint
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
The broker now also answers /api/pending from the pending/ files directly: the parked
results awaiting a decision ('Needs your eyes'), each with its human title (from the
body's '# Pending: X' heading), the candidate list (the '## Candidates' fenced-json
block), and the downstream SOP for an apply (the source SOP's first 'next:'). Ports
generate_dashboard.parse_candidates + sop_next + dashboard_app._pending into store.js,
reusing the strict-UTF-8 read so a corrupt file is skipped like Python.
Verified by semantic parity against the live FastAPI. With this, the broker serves the
static reads (plate, queue, procedures, pending) directly; FastAPI still owns settings
(its terminal field is detected from the serving process's TERM_PROGRAM env, which
differs between the broker and FastAPI, so it can't be ported cleanly) and the
liveness-bearing reads + the SSE live mirror (the Phase 5 flock/pid migration).
- desktop/store.js: parseCandidates, sopNext (non-pruned rglob-style find), pending().
- tests: candidates incl. url-title fallback, plain-heading title, next from the source
SOP, non-pending exclusion, empty when absent (23 total) + the live pending parity check.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Adversarial self-review hardening (folded into the latest push):
|
a258b13 to
7bf51bc
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
desktop/store.test.js (1)
118-125: 💤 Low valueConsider adding a test for code-point-safe truncation.
The implementation truncates titles at 140 code points, URLs at 500, and notes at 300 using
Array.from().slice()to handle astral characters correctly. A test with a long string containing emoji or other multi-byte characters would verify this edge case and serve as regression protection for the code-point vs code-unit distinction.📝 Example test for truncation
test('pending candidates: truncates by code point, not code unit', () => { const d = tmpSop(); fs.mkdirSync(path.join(d, 'pending')) const longTitle = '🎉'.repeat(150) // 150 emoji = 150 code points, but 300 UTF-16 code units fs.writeFileSync(path.join(d, 'pending', 'p.md'), '---\nstatus: pending\nsop: s\n---\n# T\n## Candidates\n```json\n' + `[{"title":"${longTitle}","url":"http://x"}]\n\`\`\`\n`) const title = store.pending(d)[0].candidates[0].title assert.equal(Array.from(title).length, 140) // truncated to 140 code points assert.ok(title.endsWith('🎉')) // no broken surrogate pairs })🤖 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 `@desktop/store.test.js` around lines 118 - 125, Add a new test function to verify that store.pending() correctly performs code-point-safe truncation for titles when handling multi-byte characters like emoji. Create a test that writes a pending markdown file with a title containing many emoji characters (which consume multiple UTF-16 code units per code point), calls store.pending(), and asserts that the resulting title is truncated to exactly 140 code points (verified using Array.from(title).length) and doesn't contain broken surrogate pairs, ensuring the implementation correctly uses Array.from().slice() instead of relying on code-unit based string operations.
🤖 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.
Nitpick comments:
In `@desktop/store.test.js`:
- Around line 118-125: Add a new test function to verify that store.pending()
correctly performs code-point-safe truncation for titles when handling
multi-byte characters like emoji. Create a test that writes a pending markdown
file with a title containing many emoji characters (which consume multiple
UTF-16 code units per code point), calls store.pending(), and asserts that the
resulting title is truncated to exactly 140 code points (verified using
Array.from(title).length) and doesn't contain broken surrogate pairs, ensuring
the implementation correctly uses Array.from().slice() instead of relying on
code-unit based string operations.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 962c2c2a-219f-4c27-bbd0-661a79f50c55
📒 Files selected for processing (3)
desktop/broker.jsdesktop/store.jsdesktop/store.test.js
Continues Phase 3: the broker now answers
/api/pending, alongside plate / queue / procedures.What moved
desktop/store.jsportsgenerate_dashboard.parse_candidates+sop_next+dashboard_app._pending: the parked results awaiting a decision ("Needs your eyes"), each with:# Pending: Xheading,## Candidatesfenced-json block →[{title,url,note}], with title falling back to url),next:), null when there are no candidates.Reuses the strict-UTF-8 read (a corrupt file is skipped, like Python).
Parity
Verified by semantic parity against the live FastAPI.
Read-migration status
The broker now serves the static reads directly:
plate,queue,procedures,pending. Still forwarded:settings— itsterminalfield is detected from the serving process'sTERM_PROGRAM, which differs between the broker and FastAPI, so it can't be ported cleanly; it stays on FastAPI.inflight,runs) and the SSE live mirror — these need the flock/pid liveness, the Phase 5 native-layer migration.Tests
node --test: 23 (pending: candidates + url-title fallback, plain-heading title, next from the source SOP, non-pending exclusion, empty-when-absent) + the live parity check.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
/api/pendingendpoint to track and retrieve parked results.Tests