feat: rename Thingtime plugin and add login command - #560
Conversation
✅ Develop S3 preview ready
The alias passed the develop bucket CORS preflight and a final live PR/SHA fence. Generic Vercel Preview deployments use the shared development runtime; this controller adds the stable exact-SHA alias and marker-scoped cleanup. |
|
Lopu review — infinite-expiry switch is well-supported; one gap fixed in this branch. I checked each layer of the The gap: revoked bridge sessions could never be reaped
Fixed at the single source of truth:
This also closes the same latent gap for never-expiring service-account sessions. Validation: Two deliberate tradeoffs worth stating out loud (no change made)
|
Lopu repository reviewLopu reviewed this PR against develop as Thingtime's principal PR and repository manager. Using Claude Opus 5. Lopu found no justified local change to publish from this review pass. Lopu review — PR #560 ·
|
|
🦄 Lopu review — one revoke path was missed Good, focused change. Reviewing this against the current Which makes the gap easier to see — the highest-frequency revoke on the bridge does not
const consumed = await (await getSessionsCollection()).findOneAndUpdate(
refreshFilter,
{ $set: { revokedAt: now, 'meta.consumedAt': now } }, // ← no reap date
{ returnDocument: 'before' }
);The Applied in this PR's worktree:
The authorization-code consumption path a few lines above is not affected: those ✅ Follow-up, out of scope here: |
🤖 Lopu live PR updateStatus: ↪️ Resolver finished; a newer conflict remains Current phase: The next detector event will own the current branch state Estimated completion: Done — no further active-work ETA. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
Technical run details — optional; this comment is the human-facing source of truth. |
🤖 Lopu detected merge conflictsStatus: Work detected — Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 12:04 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
🤖 Lopu detected merge conflictsStatus: Work detected — Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 12:58 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
🤖 Lopu live PR updateStatus: ✅ Lopu finished — this PR is mergeable Current phase: GitHub verified the published branch result Estimated completion: Done — no further active-work ETA. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
Technical run details — optional; this comment is the human-facing source of truth. |
🌿 Lopu — I watched MongoDB actually delete the rowHead Every earlier pass on this PR proved the field becomes a
The leak is real and this closes it. That is the whole claim, now observed rather than inferred. Two properties I checked because nobody had
Reaping is fail-closed. I deleted a consumed refresh row and replayed the exact The way this could have gone quietly wrongStamping a future
All seven also pin One genuine behaviour change — and why I left it aloneMoving from an update operator to a pipeline changes what happens when Measured, not guessed. But it is unreachable: On the shape-only testsThe two new tests assert pipeline shape rather than Mongo behaviour, and I think that is the right ceiling here rather than a gap worth closing: no Worth saying that the shape tests do defend the exact regression the comments fear most — Changed nothing, on purposeThe three sibling Validation
Honestly: my first Still outstanding, and it is not a code problemThe title and body still describe the plugin rename and Ship it. |
|
🤖 Lopu review — title mismatch, and a good session-lifecycle fix underneath Same pattern as #554: the plugin rename / login command is already on On the fix itself: the leak is real and the design is careful. The The best decision here is what you refused to export. Keeping Behaviour-safety check. My main concern was the side effect: a revoked
All 13 pair the expiry predicate with
Flagging your own follow-up so it does not get lost: the sibling No changes requested. |
|
Lopu review — no defects found. One housekeeping item before merge. The fix is correct and the premise is realI verified the TTL claim rather than assuming it: Keeping I checked the "safe for the same
|
| Site | Why it's safe |
|---|---|
appTokens.ts:72 |
issueAppToken always sets expiresAt = now + APP_TOKEN_TTL_MS — a real Date |
apps.ts:381 |
same; every purpose: 'app' row carries that expiry |
appLifecycleCore.ts:65 |
same |
desktopOAuth.ts:98 |
filter requires expiresAt: { $gt: now }, so the row always has a Date |
plugin.ts:636 (exchangeAuthorizationCodeGrant) |
same — 5-minute code, filter requires expiresAt: { $gt: now } |
The last two look like misses inside files this PR is already editing, but they aren't — both filters guarantee a real expiry. No gap found. Scoping and the honest follow-up note are both accurate.
Also correct: consumedSessionPipeline puts the reap stage first so meta.consumedAt can't be dropped by it (and the test pins the stage order), and aggregation $set with a dotted path merges rather than replacing meta, matching the previous plain-update semantics.
🟡 The description no longer matches the diff
The body describes three things — rename the plugin package/MCP server, add @Thingtime login / list accounts, and make bridge credentials non-expiring. GitHub's file list shows none of that remains in the delta; develop already absorbed it through the two merge commits on this branch. What's left is exactly the safety follow-up to the third bullet — the non-expiring switch is what created the unreapable-row hazard this now fixes.
Coherent work, but a reviewer reading the description will go looking for changes that aren't there, and the merge commit will describe the wrong thing. Worth retitling to the session-reaping fix and trimming the body. I haven't edited it — that's yours to word.
Validation caveat
The review worktree has no node_modules, so test:chatgpt and tsc --noEmit were not run. The two added tests are pure assertions over the pipeline shape and read correctly, but they're unverified by execution in this pass — let CI confirm.
Posted by Lopu, Thingtime's PR manager.
Lopu · the title no longer describes the branchSmall but worth fixing before merge: this PR is titled "feat: rename Thingtime plugin and add login command", but the head at On the change itself: correct, and well-scoped. The bug is real — the TTL index is The design detail I want to highlight is keeping I verified every site the PR deliberately leaves on a plain
The scoping is accurate and the comments are honest about which sites are "safe for a reason that could change" versus "fixed". No changes needed from me. |
🤖 Lopu detected merge conflictsStatus: Work detected — Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 10:20 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
🤖 Lopu detected merge conflictsStatus: Work detected — Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 10:38 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
|
🤖 Branch status still computing. The base branch moved, and GitHub had not finished recomputing whether this PR conflicts or is behind after the detector waited 500s — so no branch update was started this round. The next push or the twice-hourly scheduled sweep (minutes :02/:32) re-checks automatically. Posted by the conflict detector at 10:18 UTC, 2026-09-03; this notice is edited in place on re-checks. |
🤖 Lopu detected merge conflictsStatus: Work detected — Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 11:07 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
🤖 Lopu detected merge conflictsStatus: Work detected — Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 12:12 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
🤖 Lopu detected merge conflictsStatus: Work detected — Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 13:08 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
Summary
@Thingtime loginand@Thingtime list accountscommand mappings, backed by the existing OAuth callback and multi-account connection flowValidation
corepack pnpm --dir remix run test:chatgptcorepack pnpm --dir remix exec eslint app/api/utils/chatgpt/plugin.ts app/api/utils/chatgpt/pluginCore.ts app/api/utils/chatgpt/plugin.test.tscorepack pnpm --dir remix run buildgit diff --checkManual follow-up
@Thingtime login, complete the host OAuth callback, add two named accounts, and verify@Thingtime list accountsreports safe metadata for both.