Commit Graph
197 Commits
Author SHA1 Message Date
Jesse_ChenandClaude Opus 5 e6c6839742 test(home): follow the profile hook's return through the signOut marker
The mount-once bootstrap effect keeps its literal `}, []);` dependency array:
two existing contract tests use that exact text as a slicing landmark, so the
effect stays as it was and its existing exhaustive-deps warning simply names two
more stable setters. Only the signOut slice marker in
chat-navigation-a11y-contract moves, with the three-column note; the assertion's
subject is untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:02:22 +00:00
Jesse_ChenandClaude Opus 5 ae4573897a refactor(home): let useProfileOnboarding own the six profile states
5.3: profile / profileDraft / profileNotice / avatarNotice / avatarSaving /
profileSaving move into use-profile-onboarding.ts; Home reads them back from the
hook's return. The hook call moves above useBirthTimeGuidedJourney so profile is
defined before the first reader.

Turning the hook stateful made the React compiler lint rules apply to it, which
surfaced five errors that only a hook-shaped file gets checked for:
- two ref params written through .current (dialogReturnTarget,
  birthTimeRevisionPending) now end in "Ref" as the rule's hint asks;
- two render-phase ref writes (guidedBirthTimeReadyRef /
  editDeclaredBirthTimeDetailsRef) are gone: the hook already returns
  completeGuidedBirthTime and editDeclaredBirthTimeDetails, and now that it runs
  before useBirthTimeGuidedJourney they are passed straight in. Both callbacks
  were only ever read from render-scope closures, so the call target is the same
  function on every frame as before.

setProfile / setProfileDraft are listed in the two effects that call them; they
are raw useState setters handed through the return, so identity never changes
and neither effect gains a re-run.

Zero behavior change, zero copy change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:02:22 +00:00
Jesse_ChenandClaude Opus 5 99425fe61f refactor(home): stabilize shell setters and lower the synastry cluster
5.1: memoize createRectificationShellSetters so the four shell setters keep a
stable identity across renders, then list the two the entry-summary effect uses
in its dependency array. Lint warnings 120 -> 119 with no new warning.

5.2: move the four synastry useStates and draftSynastryQuestionFromChart into
the new useSynastry hook. Home keeps only two stable callbacks the chart-library
effect calls; the chart-library dialog receives one spread synastryPanel object.

Zero behavior change, zero copy change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:02:22 +00:00
jesse-ux f8e607c29a refactor(home): 校正面 15 个状态从 Home 下沉
Independent Staging Quality Gate / validate (push) Failing after 6m43s
Independent Staging Quality Gate / publish (push) Skipped
Home() useState 66->52, useRef 41->39. Shell-facing fields merge into one object;
subtree state lives in useRectificationSurface. Chat props 20->7. Growth contract
rebaselined. Zero behavior/copy change.
2026-09-16 08:33:48 +08:00
jesse-ux 6bb892b826 fix(chat): keep page.tsx at the 1951-line freeze after lookup wiring
Independent Staging Quality Gate / validate (push) Failing after 6m40s
Independent Staging Quality Gate / publish (push) Skipped
Move BUG-705 bootstrap selection + session lookup into
resolveLookupBootstrap so Home only awaits once. The 1951 cap in
chart-view-route.test.ts is unchanged.
2026-09-15 17:40:17 +08:00
jesse-ux f51e494c5a fix(chat): keep rectification sessions findable and keep the delivery card
Independent Staging Quality Gate / validate (push) Failing after 6m45s
Independent Staging Quality Gate / publish (push) Skipped
Rectification answers now advance chat_sessions.updated_at (BUG-704).
A ?c= id missing from the loaded page is fetched before anyone may call
it deleted (BUG-705). The range card no longer has a post-card tie-break
button; live questions leave the card visible with adopt locked
(BUG-706/708). Spoken copy bans 相对支持度 (BUG-709).

Task docs assigned 700-704; qizheng already took 700-703.
2026-09-15 17:10:53 +08:00
jesse-ux 8144fca27d fix(chat): fold natal reports and drop homepage topic cards
Independent Staging Quality Gate / validate (push) Failing after 9m47s
Independent Staging Quality Gate / publish (push) Skipped
Homepage no longer waits on /api/onboarding for six starter questions.
Natal answers show the spoken layer first; the Level 2 skeleton sits in a
collapsed 完整分析 block. Wide tables scroll sideways on a phone. Form
inputs are 16px so iOS does not zoom on focus.
2026-09-15 12:27:16 +08:00
Jesse_ChenandCursor a31a5e2426 fix(rectification): open history cases with their bound skill identity (BUG-621)
Independent Staging Quality Gate / validate (push) Successful in 9m46s
Independent Staging Quality Gate / publish (push) Successful in 32m4s
Session open was sending the live registry version into v2, so every Skill
bump rejected older cases with an unmapped 500 and no error on the clicked row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-09 19:35:23 +08:00
Jesse_ChenandCursor c9ec541164 fix(home): stop silent rectification open after login (BUG-599)
Independent Staging Quality Gate / validate (push) Successful in 13m10s
Independent Staging Quality Gate / publish (push) Has been cancelled
Bare `/` was treating the latest history session as active, so a returning account could auto-open a failed rectification Case and left-align the starter home.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-09 10:47:47 +08:00
Jesse_ChenandCursor dc6598d7e4 fix(web): keep the settings dialog one size and move billing into it (BUG-554)
The four account panes now share a fixed frame, chart profiles open as list then detail, and membership lives in the homepage dialog instead of a separate page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 18:29:51 +08:00
Jesse_ChenandCursor a1956deb63 fix(web): summarize session titles, sort by activity, and paginate history (BUG-553)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 14:34:30 +08:00
Jesse_ChenandCursor 055b7adca9 fix(web): keep composer enabled while generating and treat stop as neutral (BUG-551, BUG-552)
Enter now queues one follow-up instead of dropping it, and a rectification stop leaves the streamed reply with a grey notice instead of an error alert.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 13:08:43 +08:00
Jesse_ChenandClaude Fable 5.1 53017d4153 fix(rectification): reveal the surface once — hydrate the Case before the switch, never remount, static entry feedback
Opening a rectification Case used to switch sessions first and read the
turns afterwards, so the reader saw a plain transcript, then an empty
panel, then a remount when the turns arrived (and again after the first
turn settled, because the panel key carried a ready/loading suffix).
The surface hook now reads turns and snapshot in one Case request under
the home reveal budget and only then makes the session active; the
sidebar defers the switch the same way; a session selected at bootstrap
(deep link, refresh) is hydrated during the prepare phase so the reveal
shows the surface itself; the panel key is the session/Case binding only,
later turns fill an empty transcript as a prop update, and unmounting
aborts any stream or snapshot read. The homepage card and the sidebar row
say 正在打开 statically while the Case opens — no spinner after the reveal.

BUG-505

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-03 07:07:31 +00:00
Jesse_ChenandCursor e8c98c37cf fix(rectification): restore collect-phase exit and drop the consult handoff
Independent Staging Quality Gate / validate (push) Successful in 8m29s
Independent Staging Quality Gate / publish (push) Successful in 1m45s
Public can_adopt no longer starves the collect fallback, 改选 scrolls to
the offer, opening collect uses other, and probe_year stays on the
schema. The status bar no longer starts an empty consultation chat.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 10:41:36 +08:00
Jesse_ChenandClaude Fable 5.1 482796fc52 fix(chat): reveal the home page once after a two-phase bootstrap
The loading screen now owns every wait: starter questions, today's
starlanguage and the rectification entry summary are fetched in a prepare
phase before reveal (4s budget, static fallbacks), the rectification chunk is
warmed, recent sessions are prefetched, and no component spinner remains
after the page appears. BUG-479.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-02 04:39:04 +00:00
Jesse_ChenandClaude Fable 5.1 f542c02490 refactor(chat): share composer, scroll follow and jump control across both chat surfaces
The rectification session rendered its own textarea (no length ceiling,
no count), its own rAF scroll follow with a sticky-scroll helper, and its
own jump chip styled differently from the main chat's inline Tailwind
button, while the main chat re-ran scrollTo on every streamed token and
added a smooth scroll on settle. ChatComposer now accepts a controlled
value so the rectification surface reuses it without touching the main
draft store; useConversationScrollAnchor owns the follow through a
ResizeObserver, one frame per content change, for both surfaces; a
single JumpToLatestButton replaces both chips; the 720px transcript
override is gone. DESIGN.md records the shared composer, the jump
control, the reading width and the two shadow tokens.

BUG-477 BUG-478

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-02 04:29:01 +00:00
Jesse_ChenandCursor 058e5db9b5 fix(chat): make Home pass react-hooks lint after the split
Independent Staging Quality Gate / validate (push) Successful in 17m39s
Independent Staging Quality Gate / publish (push) Successful in 7m11s
eslint-plugin-react-hooks now analyzes the smaller Home, so render-time ref writes and sync effect setState were failing the staging gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 07:01:36 +08:00
Jesse_ChenandCursor bf6989eccf refactor(chat): extract profile onboarding and rectification surface hooks
Close the home-page split by moving account/onboarding and rectification glue out of page.tsx without relocating React state, keeping the route static and hook order intact.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 05:56:58 +08:00
Jesse_ChenandCursor 551d6317ae refactor(chat): extract consultation and session hooks after contract repairs
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Keep archive as a PATCH of archived_at rather than DELETE, pass entry_mode through onboarding, and let popstate to the default chat reuse selectSession. Then move send/stop/recovery and session management out of page.tsx so the home surface stays within the batch-two line budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 04:34:14 +08:00
Jesse_ChenandCursor 54269fcfcc refactor(chat): extract home helpers, chart library, and starter surfaces
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
page.tsx still owns the chat main chain, but the first product surfaces now
live in their own modules so later splits can land without editing the 4k-line
Home. Source-lock tests follow the moved tokens; the orphan user-data contract
is aligned and added to the quick gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 22:58:02 +08:00
Jesse_ChenandCursor ce6a8a7e72 fix(chat): make cloud the only truth for charts, synastry, and pin/archive
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Local fallbacks were creating fake saves and resurrecting deleted rows.
Pin and archive now live on chat_sessions so they follow the account.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 21:38:21 +08:00
Jesse_ChenandCursor 924f420202 fix(chat): keep the current session in the URL as ?c=
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Refresh, back, and login return were dropping the open conversation because selection lived only in React state.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 20:42:21 +08:00
Jesse_ChenandCursor b6989c3eea fix(chat): make the server the only writer of session messages
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
List GET no longer ships transcripts; consult appends questions after reserve and ignores client history so dual-tab last-write-wins cannot erase messages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 19:51:19 +08:00
Jesse_Chen 79f65ac8b0 fix(frontend): restore staging quality gate contracts
Independent Staging Quality Gate / validate (push) Successful in 10m34s
Independent Staging Quality Gate / publish (push) Successful in 10m11s
2026-08-30 17:01:01 +08:00
Jesse_Chen a671986a1d fix(frontend): complete settings MVP structure
Independent Staging Quality Gate / validate (push) Failing after 10m21s
Independent Staging Quality Gate / publish (push) Has been skipped
2026-08-30 16:32:58 +08:00
Jesse_Chen f5e6d51646 feat(frontend): bind sessions to chart profiles 2026-08-30 15:55:45 +08:00
Jesse_Chen 5c1d095f69 feat(frontend): use offline global birth place hierarchy 2026-08-30 15:55:45 +08:00
Jesse_Chen f9a00dc568 fix(frontend): preserve owner profile when switching charts 2026-08-30 15:55:45 +08:00
Jesse_Chen 796e4cf8cf feat(frontend): clarify chart profile management 2026-08-30 15:55:45 +08:00
Jesse_Chen f4fb39e0f3 feat(frontend): separate profile and chart settings 2026-08-30 15:55:45 +08:00
Jesse_ChenandCursor e8fa1ce4ea fix(frontend): raise dark contrast, expand hit areas, and surface input limits
Independent Staging Quality Gate / validate (push) Successful in 9m19s
Independent Staging Quality Gate / publish (push) Successful in 9m54s
Dark muted surfaces missed WCAG AA; action and tertiary tokens plus a 32-pair contract close that. Hit targets, remaining-count, and Enter-to-send follow the interaction audit without changing visual sizes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 11:19:50 +08:00
Jesse_ChenandClaude Opus 5 0044d4f358 fix(frontend): style the paywall header and guard undefined class names
Independent Staging Quality Gate / validate (push) Successful in 10m8s
Independent Staging Quality Gate / publish (push) Successful in 9m39s
The onboarding paywall wrote `dialog-header`, a class no stylesheet
defines, so its close button stacked under the title instead of sitting
beside it. The session-delete confirm buttons had the same problem, and a
`message-entry` wrapper added in August had quietly killed the
`.message + .message` spacing rule in the main chat.

Fixes all three against the patterns already in the codebase, then adds a
contract test so the next undefined class fails instead of shipping: it
scopes itself to our own class families so Tailwind utilities stay out,
strips CSS comments before deciding what counts as defined, and carries
an allowlist of the fifteen deliberate no-op modifiers that must shrink
rather than grow.

Also collapses the paywall's duplicate display heading into the intro
sentence, leaving one heading in the dialog.

BUG-434, BUG-435, BUG-436.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-08-29 05:40:29 +00:00
Jesse_ChenandCursor 31b54aa71d fix(frontend): say the database is missing, not Supabase
Independent Staging Quality Gate / validate (push) Successful in 9m34s
Independent Staging Quality Gate / publish (push) Successful in 7m21s
Self-hosted PostgreSQL is the runtime. A missing APP_DATABASE_URL
must not tell users the retired hosted service is unconfigured.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-29 09:44:53 +08:00
Jesse_ChenandCursor 3198fb6b2b perf(frontend): split chat streaming, load Inter, isolate admin CSS
Independent Staging Quality Gate / validate (push) Successful in 10m14s
Independent Staging Quality Gate / publish (push) Successful in 11m5s
Settled messages no longer rebuild on every token, Inter is actually
requested, and admin routes drop the 33 KB chat stylesheet. Root
force-dynamic is gone so public shells can prerender without changing
the no-store Cache-Control contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-29 03:39:43 +08:00
Jesse_ChenandCursor 04463e9af3 feat(web): show consult runs as a Lucide timeline with sliced compose
Keep provider thinking on a separate channel so process talk is not billed as the spoken reply (BUG-359).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 14:38:50 +08:00
Jesse_ChenandCursor f03a2706b4 fix(web): split rectification process talk from the spoken reply
Keep provider thinking off, classify CoT as 思考, and stop remounted sessions from firing a second opening.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 10:14:35 +08:00
Jesse_ChenandCursor 0ca7da997f fix(web): stop consultation thinking from pinching the answer
Disable provider thinking so Flash CoT cannot fill max_tokens, raise the
spoken budget to 16384, emit a server-owned step tree, and continue once
when the body ends on length.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-22 21:19:00 +08:00
Jesse_ChenandCursor 8ed6118b9a fix(web): persist uncertain birth time as a start/end clock window
Users pick a clock range instead of a coarse period plus notes, so
rectification and window consult scan that range instead of a leftover afternoon bucket.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-22 20:48:01 +08:00
Jesse_ChenandCursor 92558ee61d fix(web): stack mobile audit tables and restore sidebar hierarchy
Independent Staging Quality Gate / validate (push) Successful in 9m27s
Independent Staging Quality Gate / publish (push) Successful in 7m40s
Narrow screens were wrapping 已执行 into a glyph column and painting every sidebar row the same gray, so history looked like top-level chrome.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-22 09:57:06 +08:00
Jesse_ChenandCursor 59559d4b24 fix(web): persist thinking, title sessions distinctly, and send follow-ups from the answer
Thinking disappeared on failure and never reached session storage. Keep the
sanitized chain on disk and on errors, and regroup the sidebar around reports,
charts, favorites, and dated history titles.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-22 09:10:47 +08:00
Jesse_ChenandCursor 649ba32034 fix(home): send starter cards instead of filling the composer
Independent Staging Quality Gate / validate (push) Successful in 11m21s
Independent Staging Quality Gate / publish (push) Successful in 17m56s
Clicking today's reading or a topic card should open a consultation and wait for the model, not leave the question in the input box.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 22:02:40 +08:00
Jesse_ChenandCursor 4e247c112e fix(web): keep thinking off the spoken consult and rectification answer
Enumerate evidence kinds so education cannot be proposed as a kind, and stream Chinese thinking on a separate channel that collapses when the reply arrives.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 21:30:55 +08:00
Jesse_ChenandCursor 9958e00abc fix(web): keep unrectified birth data usable without inventing a minute
Rectification stays optional. Reported minutes can consult and generate reports; date-plus-period uses a declared window instead of a midpoint or 00:00. Updates BUG-341.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 15:29:58 +08:00
Jesse_ChenandCursor 6a44c778c3 fix(web): show live agent work progress and fail truncated rectification answers
Rectification dropped tool.activity started events and treated length finishes as completed. Share generation settings with consultation, keep the activity line through streaming, and name multi-domain chart calculation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 12:39:09 +08:00
Jesse_ChenandCursor f4619df273 fix(web): portal the natal board peek without effect setState
Quality gate lint failed on setHeaderSlot inside useLayoutEffect, so staging never published. Pass the header mount node from a callback ref instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 11:03:57 +08:00
Jesse_ChenandCursor 50e1a4aca5 fix(web): reload stale clients instead of spinning after a release
Homepage bootstrap never escaped the loading shell when a new web image changed chunk hashes. Stamp deploymentId, stop caching chat HTML, and hard-reload failed chunk loads once.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 10:29:43 +08:00
Jesse_ChenandCursor 8b8e5214f9 fix(web): keep onboarding and mobile natal board on one aligned overlay
Put the compact board trigger in the chat header, keep the sheet above the composer on iOS, and align onboarding messages with the intake card on the session column.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 23:54:20 +08:00
Jesse_ChenandCursor e07d1bada4 fix(rectification): show natal houses and lagna changes in a live right rail
The board was live data sitting under chat, so each new event looked like nothing changed. Keep candidate cards in the transcript and group 换升 by minute for the side panel.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 14:24:05 +08:00
Jesse_ChenandCursor a3196584d2 feat(rectification): add refinement packet without unique-minute claims
Surface D9/D10 change minutes, event-dasha match copy, dual-dasha conflict, and a post-adopt consult handoff so users can keep narrowing or start a reading from a representative time.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 07:47:10 +08:00
Jesse_ChenandCursor 7d667fecbf fix(consult): treat pinched answers as failed and restore reply actions
Incomplete Flash generations were billed as completed consultations. Fail
those runs, keep the partial text, and reuse the rectification like/copy/rerun
bar on ordinary chat replies.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 19:40:50 +08:00