Skip to content

fix(ci): drop linux/arm64 build, keep amd64 only#2

Merged
zjean merged 1 commit intomainfrom
fix/drop-arm64-build
Apr 22, 2026
Merged

fix(ci): drop linux/arm64 build, keep amd64 only#2
zjean merged 1 commit intomainfrom
fix/drop-arm64-build

Conversation

@zjean
Copy link
Copy Markdown
Owner

@zjean zjean commented Apr 22, 2026

arm64 via QEMU emulation added ~20 min to every image build and we have no arm64 deployment target. Also removes the QEMU setup step that was only needed for cross-arch builds.

Context

Test plan

  • `test` check green
  • After merge, verify `build-image.yml` completes in a normal ~2-5 min range and publishes `ghcr.io/zjean/sync-in-server:main` + `:sha-`.

arm64 via QEMU emulation added ~20 minutes to every build and we have
no arm64 deployment target. Also remove the QEMU setup step that was
only needed for cross-arch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@zjean zjean merged commit f10b37d into main Apr 22, 2026
1 check passed
@zjean zjean deleted the fix/drop-arm64-build branch April 22, 2026 09:47
zjean added a commit that referenced this pull request Apr 22, 2026
…#8)

## Summary

PR #1 of 6 from the approved [v2 UI redesign
plan](../blob/main/docs/plans/2026-04-22-v2-ui-redesign-design.md).
Scaffolds the empty \`custom-v2/\` skeleton, mounts a stub "Sync-In v2 —
coming soon" at \`/v2\`, wires design tokens scoped under \`.v2-root\`,
and adds an opt-in "Try redesigned UI" link in the classic user-profile
sidebar with \`localStorage\` stickiness.

After merge, visiting \`/v2\` renders the dark token palette and
Instrument Serif greeting; classic routes are untouched unless the user
has opted into v2 (in which case they redirect back to \`/v2\`, with an
escape hatch on the stub page).

## What's here

**Additions under \`frontend/src/app/applications/custom-v2/\`**
(conflict-free with upstream):
- \`v2.constants.ts\`, \`ui-version.ts\`, \`ui-version.guard.ts\` —
route path + localStorage plumbing.
- \`layout/layout-v2.component.*\` — mounts \`.v2-root\` with
\`ViewEncapsulation.None\`, loads \`v2.scss\`.
- \`screens/stub/stub.component.*\` — placeholder with "Back to classic
UI".
- \`styles/_tokens.scss\` — SI tokens and FILE_COLORS from the handoff
bundle's \`tokens.jsx\`, with hex fallbacks before \`oklch()\` for
Safari <15.4.
- \`styles/v2.scss\` — font imports (latin-only subsets for Instrument
Serif to stay under the 8 kB \`anyComponentStyle\` budget; total ~4 kB)
+ base \`.v2-root\` rules.
- \`v2.routes.ts\` — child routes: just the stub for now.

**Upstream file modifications** (small and atomic — grep \`git log
--grep '^mod('\` to audit):
- \`frontend/src/app/app.routes.ts\` — adds the \`/v2\` sibling route
group and attaches \`uiVersionGuard\` to the classic layout.
-
\`frontend/src/app/applications/users/components/sidebar/user-profile.component.{ts,html}\`
— adds one "Try redesigned UI" link next to Website / Versions.
- \`frontend/package.json\` + \`package-lock.json\` — three new
\`@fontsource\` packages (\`geist\`, \`instrument-serif\`,
\`jetbrains-mono\`).

## Out of scope (future PRs)

Chrome (TitleBar / AppRail / LeftNav / DockRail) lands in PR #3; icons +
primitives in PR #2; Recents / Personal / Viewer screens in PRs #4#6.
AGPL §13 source-link goes in the left-nav user-card footer (PR #3).

## Test plan

- [x] \`npm run lint\` — clean
- [x] \`npm run build\` (production) — clean, no budget warnings
- [x] \`npm run build:dev\` — clean
- [ ] Manual smoke: log in → open user-profile sidebar → click **Try
redesigned UI** → lands on \`/v2\` with dark palette + Instrument Serif
greeting → reload any classic route → sticky redirect returns you to
\`/v2\` → click **Back to classic UI** → sticky cleared, classic
behaviour restored.

Manual smoke not verified in this session (no authenticated dev login);
reviewer please confirm on checkout.

## Risks

- **Font package weight** — three \`@fontsource\` packages ship as
bundled \`@font-face\` declarations; only v2 routes reference the
families, so classic clients pay the small CSS parse cost but never
download WOFF2 binaries.
- **Stickiness trap** — \`Back to classic UI\` in the stub clears
\`localStorage.ui.version\`, so the escape hatch is always reachable;
guard only redirects, never blocks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
zjean added a commit that referenced this pull request Apr 22, 2026
)

## Summary

PR #2 of 6 from the [v2 UI redesign
plan](../blob/main/docs/plans/2026-04-22-v2-ui-redesign-design.md).
Ports the icon set and primitive components from the handoff bundle and
adds a \`/v2/_kit\` route for visual review.

No upstream files modified — everything lives under
\`frontend/src/app/applications/custom-v2/\`.

## What's here

### Icons (\`icons/icon-v2.component.*\`)
Single \`IconV2Component\` rendering all **57 glyphs** from
\`icons.jsx\`:
- Typed \`IconV2Name\` union so the compiler catches typos at every call
site.
- 24×24 viewBox, 1.6 stroke, \`currentColor\`, round caps/joins.
- Inputs: \`name\` (required), \`size\` (default 18), \`stroke\`
(default 1.6).
- Template is one \`@switch\` on \`name\` — trivial to grep, zero
runtime cost vs a per-icon file.

### Primitives (\`components/*.component.ts\`)
All \`ChangeDetection.OnPush\`, signal inputs where computed styles are
needed:

| Component | Purpose |
|---|---|
| \`AvatarComponent\` | Hue-driven gradient circle with initials +
optional ring |
| \`AvatarStackComponent\` | Overlapping avatars with \`+N\` overflow |
| \`FileGlyphComponent\` | Type-colored square using \`--fc-*\` tokens,
mapped to matching file-type icon |
| \`LogoComponent\` | Conic-gradient plum/terracotta mark with inner
ring and centered dot |
| \`PillComponent\` | 8 color variants (gray / indigo / green / amber /
rose / violet / cyan / warm) consuming semantic tokens via content
projection |
| \`ButtonComponent\` | 5 kinds × 4 sizes, optional leading/trailing
icon slots |
| \`IconButtonComponent\` | Square icon-only button with active state
for nav rails |

### Kit showcase (\`screens/kit/\`)
\`/v2/_kit\` renders every primitive in its variant matrix: all icons in
a labelled grid, avatar variants, file-glyphs per type, every pill
color, every button kind × size combo, icon-button states. A small
\"Design kit →\" link on \`/v2\` routes reviewers there. Not linked from
production flows.

## Consumed by future PRs

- PR #3 (chrome): TitleBar uses \`LogoComponent\` +
\`IconButtonComponent\`; AppRail/LeftNav/DockRail use
\`IconV2Component\`; LeftNav user card uses \`AvatarComponent\`.
- PR #4 (Recents): comment rows use \`AvatarComponent\` +
\`FileGlyphComponent\`; Files rows use \`FileGlyphComponent\` +
\`PillComponent\` for badges.
- PR #5 (Personal browser): toolbar uses \`ButtonComponent\`; row
selection state uses \`IconButtonComponent\`; columns use
\`PillComponent\`.
- PR #6 (Viewer): overlay controls use \`IconButtonComponent\`.

## Test plan

- [x] \`npm run lint\` — clean (autofix applied to 3 prettier-formatted
templates)
- [x] \`npm run build --configuration production\` — clean, no budget
warnings
- [ ] Manual smoke: log in → click **Try redesigned UI** → click
**Design kit →** → review every variant matrix renders correctly and
tokens resolve.

Manual smoke not verified in this session (no authenticated dev login);
reviewer please confirm on checkout.

## Risks

- **Large \`@switch\` in icon-v2.component.html** (~160 lines).
Angular's compiler handles this fine, and the alternative (one file per
icon or runtime lookup with \`innerHTML\` + sanitizer bypass) is
strictly worse. Grepable by name.
- **Prettier's multiline transition expansion** on \`button\` and
\`icon-button\` components — cosmetic only, applied by \`ng lint
--fix\`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
@zjean zjean mentioned this pull request Apr 23, 2026
3 tasks
zjean added a commit that referenced this pull request Apr 23, 2026
## Summary

PR #2 of 9 in [milestone
3](../blob/main/docs/plans/2026-04-23-v3-ui-redesign-milestone3.md).
Replaces the \`/v2/spaces\` placeholder with a real Spaces index table
backed by \`SpacesService.listSpaces\`.

**Stacked on [#16](../pull/16) — GitHub auto-retargets to \`main\` when
#16 merges.**

## What's here

- Toolbar with Refresh / Create space / More icon buttons and a
right-aligned \`<n> spaces\` count.
- Sticky column header (Name / Quota / Members / Modified) + row table
sorted by \`modifiedAt desc\`.
- Rows: indigo-soft box glyph + name + description; quota cell shows
\`usage / quota\` via \`ToBytesPipe\` (falls back to usage-only when
unlimited); members count aggregates users + groups from
\`SpaceModel.counts\`; modified uses a violet pill with \`TimeAgoPipe\`.
- Row click opens \`/spaces/files/<alias>\` (classic) so deep-linking
into a space works even though the space browser itself isn't v2 yet.
- Create button routes to classic \`/spaces?new=1\` so the existing
Create Space flow stays reachable.

## Scope adjustment

The v2-native Create Space modal was scoped to a follow-up PR to keep
this one focused. The plan's §3 note permits this ("Settings tab is the
minimum viable scope; Files/Members/Links tabs show their placeholder
content … can be filled in follow-up work"). Tracking as
\`feat/v3-spaces-create-modal\` — will open when the rest of milestone 3
has landed enough primitives (form inputs, modal shell) to make it
cheap.

## Test plan

- [x] \`npm run lint\` — clean
- [x] \`npm run build --configuration production\` — clean, no budget
warnings
- [ ] Reviewer smoke: \`/v2/spaces\` lists real spaces;
loading/empty/error states render; Refresh re-fetches; Create button
navigates to classic.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
zjean added a commit that referenced this pull request May 4, 2026
…detail Prev/Next history stacking (#150)

## Summary

- **Fix #1 — comments pill now opens the preview overlay** (personal +
space-files screens): `openComments` was routing to the heavier
`/v2/file` full-screen route. Since the preview overlay gained its own
Comments tab in #149, the pill now calls
`PreviewOverlayService.open(path, file, { initialTab: 'comments' })`.
`PreviewOverlayService` gets a new `PreviewOpenOptions` param + a plain
`initialTab` getter; `PreviewComponent` reads that getter on each path
change and auto-opens the info aside when `comments` is requested.

- **Fix #2 — Prev/Next in file-detail no longer stacks history
entries**: `goTo()` was missing `replaceUrl: true`, so each sibling
navigation pushed a new browser history entry. `close()` only walked
back one entry, forcing the user to click Close once per Prev/Next
pressed. Adding `replaceUrl: true` makes Prev/Next mutate the URL in
place; Close exits in a single click.

## Files changed

| File | Change |
|---|---|
| `preview-overlay.service.ts` | Add `PreviewOpenOptions` interface,
`initialTab` getter, extend `open()` signature |
| `preview.component.ts` | Apply `overlay.initialTab` on each path
change; auto-open info aside for comments |
| `personal.component.ts` | `openComments` → overlay with `initialTab:
'comments'` |
| `space-files.component.ts` | Same |
| `file-detail.component.ts` | `goTo()` + `replaceUrl: true` |

## Test plan

- [ ] Click the comments pill on a file row in `/v2/personal` → preview
overlay opens with Comments tab active and info aside expanded
- [ ] Click anywhere else on the same row → preview overlay opens with
Info tab (existing behavior preserved)
- [ ] Same two checks in `/v2/spaces/<alias>`
- [ ] In `/v2/file?path=…` (direct deep-link), click Next/Prev several
times → URL mutates, Close exits in a single click
- [ ] `ng lint` and `tsc --noEmit` pass (verified locally)

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-authored-by: Claude Sonnet 4.6 (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