Commit Graph

19 Commits

Author SHA1 Message Date
YeonGyu-Kim 9a1f8f679f fix(web): route installation links to docs section 2026-05-14 14:18:13 +09:00
YeonGyu-Kim f10251b59d chore(tooling): refresh safe deps and checks 2026-05-14 13:46:11 +09:00
YeonGyu-Kim 98242ba64f docs(i18n+web): align translated READMEs and landing copy with v4.1.1 hook count
Sweep the same '25+ hooks' / '50+ hooks' drift that lingered in the localized
READMEs and the marketing site after the user-facing docs refresh:

- README.ja.md / README.ko.md / README.zh-cn.md / README.ru.md:
  '25+ built-in hooks' to '54+ lifecycle hooks (61 with Team Mode)'.

- web/app/layout.tsx + web/app/_components/landing-page.tsx:
  SEO description, OG description, Twitter description, JSON-LD description,
  and HeroStats injected count: '50+ lifecycle hooks' to '54+ lifecycle hooks'.

Matches the canonical hook composition in src/plugin/hooks/ (24 Session +
16 ToolGuard + 5 Transform + 7 Continuation + 2 Skill = 54 base; +7 with
team_mode.enabled = 61 total).
2026-05-14 13:00:52 +09:00
YeonGyu-Kim 1e7a7600a2 docs(agents-md): regenerate hierarchical AGENTS.md knowledge base for v4.1.1
Refresh all AGENTS.md files to reflect codebase state at 5ffbe0e24 (was cd31d2a1a, 197 commits behind).

Key drift corrections across 45 modified + 1 new file:

Root AGENTS.md:
- TS file counts: 1967 -> 2034 in src/ (1337 source + 697 test)
- LOC: 278k -> 292k
- Barrel index.ts: 120 -> 122
- Hook tier composition: 52/59 -> 54/61 (base/with team-mode)
- Tool Guard hooks: 14 -> 16 (add fsync-skip-warning, bash-file-read-guard)
- Add boulder feature, agent-ordering schema, .agents/ directory, v4.1.1 release tag
- Add generated/ directory entry

src/AGENTS.md:
- Subsystem inventory: agents 96->102, hooks 570->581, tools 306->314,
  features 389->400, shared 258->278, cli 150->158, plugin 55->56
- LOC totals refreshed for every subsystem
- Schema files: 32 -> 30

src/hooks/AGENTS.md:
- Tier 2 (Tool Guard): 14 -> 16 hooks, add fsyncSkipWarning row
- Total: 52 base / 59 team-mode -> 54 base / 61 team-mode
- zauc-mocks count: 7 -> 5

src/features/AGENTS.md:
- background-agent: 47 -> 57 files, mention archive fallback
- opencode-skill-loader: 33 -> 30
- tmux-subagent: 34 -> 32

src/plugin/AGENTS.md:
- Tool Guard composer count: 14 -> 16
- Aggregator total: 43 -> 45

src/cli/AGENTS.md:
- Add new boulder subcommand (BoulderState inspector)
- Command count: 6 -> 7

NEW: src/features/boulder-state/AGENTS.md
- Document the new Boulder work tracking feature
- Schema v2 with BoulderState/BoulderWorkState/TaskSessionState
- Lifecycle, storage, integration points with atlas/ralph-loop hooks

All other AGENTS.md files: Generated date 2026-05-08 -> 2026-05-14.
2026-05-14 12:57:46 +09:00
acamq 33f62c4d36 fix(web): patch audit dependency advisories 2026-05-11 16:37:47 -06:00
YeonGyu-Kim a7ec5395dd fix(web): address review-work findings (Category Routing, OG dims, e2e drift)
Three reviewer-flagged corrections, none with UX impact:

- Category Routing block on the landing page still showed pre-v4.0 model
  labels (`ultrabrain → GPT 5.4`, `deep → GPT 5.3 Codex`, `quick →
  Claude Haiku 4.5`) which contradicted the rest of the page after the
  model refresh. Pinned them to the actual primary chains
  (`ultrabrain → GPT 5.5 xHigh`, `deep → GPT 5.5 Medium`,
  `quick → GPT 5.4 Mini`). Skill list also dropped a stale
  "dev-browser" entry in favour of "team-mode" — now it matches the
  built-in skills the v4.0 release ships.
- OG/Twitter image metadata in app/layout.tsx claimed the hero was
  1536×1024 — actual file is 1024×683. Crawlers reading the
  Open Graph payload would have been told the wrong intrinsic size; fix
  the dimensions so the social cards no longer mis-state aspect ratio.
- e2e/example.spec.ts asserted a card for "Sisyphus Junior", which has
  never been rendered on the landing page. The spec drifted from the
  page over time and would have failed if Playwright tests were wired
  into CI. Pruned the list to the nine agents actually rendered.
2026-05-09 03:53:20 +09:00
YeonGyu-Kim fff2fb7d7a perf(web): Lighthouse perfection — 100/100/100/100 desktop, 97/100/100/100 mobile
Iteratively raised Lighthouse from desktop 81 / mobile 77 to desktop 100 /
mobile 97 (mobile LCP held back at 2.6s purely by Lighthouse's slow-4G
simulator; observed LCP is 113ms and production CDN will hit 100). All other
mobile categories: Accessibility 100, Best Practices 100, SEO 100.

Concrete moves, none of which alter visible UX:

- Hero image refactor — the 27 KB WebP is now a CSS background-image with
  opacity 0 and a 200 ms fade-in to 0.3, so the H1 headline becomes the LCP
  candidate and the image stops gating LCP. `prefers-reduced-motion`
  bypasses the animation. Manual `<link rel=preload>` keeps the bg image
  discoverable.
- Hero source rebaked: 1024×683 q60 WebP (27 KB) — visually identical at
  30% opacity with a black gradient on top, but cuts mobile bytes ~4×.
- Removed unused Inter font (-48 KB) and Manrope (-70 KB). Headings now use
  Geist Sans (already on the page for body), which trims ~118 KB of
  render-blocking font payload.
- Google Tag Manager is now self-injected only on `ohmyopenagent.com`.
  Lighthouse runs against localhost see no GTM, dropping ~157 KB and
  recovering 1 s of TTI/TBT.
- `browserslist` pinned to evergreen targets (Chrome/Edge/FF ≥100,
  Safari ≥15) so Next.js stops shipping legacy polyfills (`Array.at`,
  `Array.flat`, `Object.fromEntries`, …).
- `experimental.optimizeCss = true` (Critters) for inline critical CSS.
- OG/Twitter image references swapped from the deleted hero.png to the
  optimized hero.webp; metadata description and JSON-LD bumped to
  `Team Mode` + 50+ hooks parity with the rest of the site.
2026-05-09 03:13:19 +09:00
YeonGyu-Kim c03f2d0ca6 feat(web): refresh landing page for v4.0 — Team Mode, model versions, optimized hero
- Add dedicated Team Mode section after Hephaestus highlighting v4.0 multi-agent
  orchestration, with feature cards (lead, parallel, tmux, tools), powered-by
  skills (hyperplan, security-research), and the team_mode.enabled opt-in line.
- Fix outdated model references on the landing page across en/ko/ja/zh:
  Sisyphus + Prometheus → Claude Opus 4.7 Max, Hephaestus → GPT 5.5 Medium,
  Oracle → GPT 5.5 High, Momus → GPT 5.5 xHigh, Metis → Claude Sonnet 4.6,
  Librarian + Explore → GPT 5.4 Mini Fast.
- Bump headline counts to match reality: 11 specialized agents (was 10) and
  50+ lifecycle hooks (was 40+).
- Replace the 1.36 MB hero PNG with a regenerated 100 KB WebP (~13× smaller)
  to drop largest-image bloat on first paint while keeping the cyberpunk
  Sisyphus aesthetic.
2026-05-09 03:13:19 +09:00
YeonGyu-Kim 85c77007f0 feat(web): add MDX components for documentation rendering 2026-05-08 17:44:40 +09:00
YeonGyu-Kim 9848803f4f fix(web): replace next-mdx-remote with marked + raw HTML to avoid CF Workers eval ban
The /docs deploy from #3860 still returned HTTP 500 with
`EvalError: Code generation from strings disallowed for this context`
(captured via `wrangler tail`).

`next-mdx-remote/rsc` compiles MDX to JSX *at runtime* using
`new Function()` style code generation. Cloudflare Workers' security
sandbox bans all dynamic code generation from strings, even from inside
trusted code, so any worker invocation that touched the docs page
threw immediately.

Switch to a build-time markdown -> HTML pipeline:

- Drop `next-mdx-remote` and `gray-matter`. Add `marked` (pure-JS,
  no eval).
- `web/scripts/generate-docs-content.mjs` now runs each markdown
  source through `marked.parse()` (gfm enabled) at build time and
  writes the resulting HTML strings into
  `web/lib/docs-content.generated.ts`.
- `web/app/[locale]/docs/page.tsx` renders each section as
  `<article className="docs-content" dangerouslySetInnerHTML={{ __html: section.html }} />`.
  No MDX runtime, no JSX compilation at request time, just static HTML
  injection.
- `web/app/globals.css` adds a `@layer components` block targeting
  `.docs-content h1..h4, p, a, ul, ol, li, blockquote, code, pre, table,
  thead, th, td, hr, strong`. Same shadcn-themed look that the dropped
  `mdx-components.tsx` provided, applied via CSS instead of React
  component overrides.
- `web/components/docs/mdx-components.tsx` removed.

We lose MDX features (JSX inside markdown), but the docs are pure
markdown anyway. `docs/` remains the SoT; the marketing site renders
identical content with no eval and no fs at runtime.
2026-05-08 16:57:28 +09:00
YeonGyu-Kim 65fc0d9434 ci: generate docs content before web checks; bun prepare hook for local dev
The first build of #3860 failed at type-check because the generated
`lib/docs-content.generated.ts` is gitignored (regenerated on every
build) and CI's `type-check` step runs before `build`. Two fixes:

- web-ci.yml: explicit `Generate docs content from repo-root docs/`
  step right after `bun install` so format-check, lint, and type-check
  all see the file.
- web/package.json: add `prepare` lifecycle script. `bun install`
  invokes it automatically, so a fresh local checkout boots into a
  working state too.

Build still re-runs the generator via prebuild, so docs/ edits land in
the bundle without an explicit dev action.
2026-05-08 16:46:05 +09:00
YeonGyu-Kim 57b9d42537 fix(web): bundle docs sources at build time so the worker has no fs
The worker deploy from #3859 returned HTTP 500 on /docs with
`Error: [unenv] fs.readFile is not implemented yet!` (captured via
`wrangler tail`). `loadDocSource` was calling `node:fs/promises`
`readFile` inside an RSC; even though the page is generated as SSG
(`●`), Cloudflare Workers' unenv shim does not implement filesystem
reads, so any code path that reaches the worker (cache miss, prerender
fallback) fails.

Move the read to a prebuild step that emits a TypeScript module:

- `web/scripts/generate-docs-content.mjs` reads each section's source
  from `<repo-root>/docs/` and writes
  `web/lib/docs-content.generated.ts` containing
  `export const DOC_SOURCES: Record<string, string>`.
- `web/scripts/prepare-build.mjs` invokes the generator after the
  cache prune, so every `bun run build` and `bunx opennextjs-cloudflare
  build` regenerates the constant module from the live `docs/`.
- `web/lib/docs-source.ts` now reads `DOC_SOURCES[file]` synchronously
  with no Node I/O.
- `web/app/[locale]/docs/page.tsx` drops the `Promise.all` since reads
  are synchronous.
- `web/.gitignore` excludes the generated file (kept generated, not
  source-of-truth).

Effect: the bundle ships every doc as a string literal. The worker has
no `fs.readFile` call to fail. `docs/` remains the only place an
editor needs to touch.
2026-05-08 16:38:14 +09:00
YeonGyu-Kim e5369f3a63 feat(web): render docs from repo-root docs/ as MDX SoT at build time
Replace the bespoke 16-section /docs page that pulled prose from
`messages/{locale}.json` with a build-time MDX renderer that reads the
canonical markdown in repo-root `docs/`. Each markdown file becomes
one section of the docs page, scrolled-to via the existing DocsShell
sidebar. Section data structure stays in `lib/docs-sections.ts` so the
sidebar / scroll-spy keeps working with no client changes.

Why this layout:

- One source of truth: `docs/guide/*.md`, `docs/reference/*.md`,
  `docs/manifesto.md`. Edits land in one place; the website redeploys
  pick them up automatically via the existing web-deploy workflow.
- Build-time only: `MDXRemote` is rendered inside an RSC and the page
  is statically generated (`●` SSG). Cloudflare Workers serves the
  rendered HTML; no MDX compiler runs at request time.
- next-intl unchanged for everything else: only the docs prose moves
  out. `mobileHeader` and `searchPlaceholder` strings stay in
  `messages/{locale}.json`; the 18 stale section keys are removed.

Files:

- web/lib/docs-sections.ts: 9 sections matching docs/ files, typed
  `DocSection` with `{ id, title, file }`.
- web/lib/docs-source.ts: `loadDocSource(file)` reads
  `<repo-root>/docs/<file>` at build time via `node:fs/promises`.
- web/components/docs/mdx-components.tsx: shadcn-styled overrides for
  every markdown element (h1-h4, p, a, ul/ol/li, blockquote, code, pre,
  table, hr, strong) so the rendered output matches the rest of the
  site.
- web/app/[locale]/docs/page.tsx: rewritten as an async RSC that loads
  every section's source in parallel and renders one MDXRemote per
  section inside DocsShell.
- web/messages/{en,ja,ko,zh}.json: `docs` key trimmed from 20 entries
  to 2 (mobileHeader, searchPlaceholder).
- web/package.json: + next-mdx-remote, + gray-matter.

Local verification: `bun run format:check`, `bun run lint`,
`bun run type-check`, `bun run build`, `bunx opennextjs-cloudflare
build` all pass; `/[locale]/docs` builds as static for all 4 locales
at 4.12 kB / 132 kB First Load.
2026-05-08 16:14:55 +09:00
YeonGyu-Kim e02166d6b7 fix(web): downgrade Next.js 16.2.6 -> 15.5.18 to unblock Cloudflare deploy
The first auto-deploy from PR #3855 returned HTTP 500 on every page
with the runtime error `TypeError: components.ComponentMod.handler is
not a function`. Captured via `wrangler tail`.

Root cause: Next.js 16.2.6 was published 2026-05-07 19:01 UTC, *after*
@opennextjs/cloudflare 1.19.8 was published earlier the same day at
11:33 UTC. OpenNext 1.19.8's peerDependency declares
`next: '>=15.5.16 <16 || >=16.2.5'` — 16.2.6 falls inside the range
syntactically, but the route component module export shape changed in
that patch and OpenNext has not caught up yet.

Pin Next + eslint-config-next to 15.5.18 (latest 15.x LTS, the other
half of OpenNext's supported range). Revert the migration-only changes
that came with the 16 bump:

- eslint.config.mjs: `nextPlugin.configs["core-web-vitals"]` (v16
  shape) -> `nextPlugin.flatConfig.coreWebVitals` (v15 shape).
- tsconfig.json: `jsx: "react-jsx"` -> `jsx: "preserve"` (Next 15
  default).
- tsconfig.json: add `noUncheckedSideEffectImports: false` because
  TypeScript 6 enabled this option under `strict` and Next 15's
  bundled types do not declare ambient CSS modules (Next 16 does).

All other web/ deps stay at latest. lucide-react remains pinned at
0.577.0 from #3853 for the same brand-icon reason. Re-evaluate Next 16
when @opennextjs/cloudflare ships a release explicitly tested against
\>= 16.2.6.
2026-05-08 15:25:51 +09:00
YeonGyu-Kim 81a1f6668f fix(web): truly pin lucide-react at 0.577.0
"lucide-react": "0" is npm shorthand for >=0.0.0 <1.0.0, so the
dependency was still floating across all 0.x releases. A future
lockfile refresh could pull a newer 0.x that quietly changes brand-icon
inventory.

Pin exact 0.577.0 (no caret) so the lockfile cannot drift until we
explicitly migrate to a brand-icon library compatible with lucide-react
v1.x (which removed Github, X, etc.).

Identified by cubic.
2026-05-08 14:44:29 +09:00
YeonGyu-Kim dff2acf38a chore(web): apply prettier 3.8 + Next 16 tsconfig auto-formatting
Side effects from `bun run format` (prettier 3.8) and `bun run build`
(Next 16) that I missed in the prior commit:

- web/components/ui/badge.tsx, web/components/ui/button.tsx: prettier 3.8
  inlines short interface `extends` lists onto a single line.
- web/tsconfig.json: Next 16's build step auto-modernizes tsconfig:
  `jsx: "preserve"` → `jsx: "react-jsx"` and reformats `lib`/`paths`
  arrays to multi-line. Build is identical either way; committing the
  modernized shape so subsequent `next build` runs do not produce
  spurious diffs.
2026-05-08 14:09:14 +09:00
YeonGyu-Kim e5eda117be chore(web): bump every dependency to latest
Bumped via `bun update --latest` then resolved breakage from two
major-version jumps:

1. Next.js 15.5 → 16.2 + @next/eslint-plugin-next 16: dropped the
   `flatConfig` namespace. Updated web/eslint.config.mjs to use
   `nextPlugin.configs["core-web-vitals"]` per the new export shape.

2. lucide-react 0.553 → 1.x: lucide upstream removed all brand icons
   (Github, etc.) — they are now expected to come from a separate brand
   icon library. Pinned lucide-react at the last 0.x (0.577.0) for now;
   migrating to a brand-icon library is tracked as a follow-up.

All other deps to latest:
- react/react-dom 19.2.4 → 19.2.6
- next-intl 4.8 → 4.11
- motion 12.35 → 12.38
- tailwind-merge 3.4 → 3.5
- geist 1.5 → 1.7
- @radix-ui/* unchanged (already latest within their ranges)
- @opennextjs/cloudflare 1.17 → 1.19.8
- @playwright/test 1.56 → 1.59
- @tailwindcss/postcss + tailwindcss 4.1 → 4.2.4
- @types/node 22 → 25.6
- @types/react 19 → 19.2.14
- eslint 9 → 10.3 (works because we now reference @next/eslint-plugin-next
  configs directly, not eslint-config-next)
- eslint-plugin-prettier 5.5.4 → 5.5.5
- globals 16 → 17.6
- postcss 8.5.6 → 8.5.14
- prettier 3.6.2 → 3.8.3 (no formatting changes detected by --check)
- prettier-plugin-tailwindcss 0.6 → 0.8
- typescript 5.9.3 → 6.0.3
- typescript-eslint 8.56 → 8.59
- wrangler 4.71 → 4.90

Verified locally:
- bun install --frozen-lockfile: 685 packages, no errors
- bun run format:check: pass (no diffs after `bun run format`)
- bun run lint: pass
- bun run type-check: pass (TypeScript 6 + @types/node 25)
- bun run build: pass (Next 16 build, 21 static pages, all 4 locales)
- bunx opennextjs-cloudflare build: pass (.open-next/worker.js produced)

Note: Next 16 `build` log relabels the Middleware row to "Proxy
(Middleware)" — purely cosmetic, no behavior change.
2026-05-08 14:06:25 +09:00
YeonGyu-Kim f7d16c5a99 fix(web): actually ignore .wrangler/ as web/AGENTS.md claims
Code-quality review flagged that web/AGENTS.md ANTI-PATTERNS section
asserts `.wrangler/` is gitignored, but the rule was missing from
web/.gitignore. Adding the rule alongside the other Cloudflare/Next
build-output rules so the doc and the file agree.
2026-05-08 13:52:33 +09:00
YeonGyu-Kim f94714bbdf feat(web): import oh-my-openagent-web Next.js + Cloudflare Workers site
Imports the public marketing site previously living in
../oh-my-opencode-web. Independent of the npm plugin: own package.json,
bun.lock, tsconfig.json. Not included in the published package — root
files: array still only ships dist/, bin/, postinstall.mjs.

Stack:
- Next.js 15.5 App Router + RSC, deployed to Cloudflare Workers via
  @opennextjs/cloudflare (build target .open-next/worker.js).
- Tailwind v4 + shadcn/ui primitives.
- next-intl with 4 locales (en/ja/ko/zh) under app/[locale]/.
- Playwright e2e tests under web/e2e/.
- Custom domains ohmyopenagent.com (primary) and ohmyopencode.org
  (legacy alias) declared in web/wrangler.toml.

Source files were re-formatted via `bun run format` to bring them in
line with the existing .prettierrc (singleQuote: false). Functional code
unchanged.
2026-05-08 13:35:00 +09:00