Commit Graph
1924 Commits
Author SHA1 Message Date
Ken JoandClaude Fable 5 8ca114c473 fix(opencode): string-aware JSONC stripping via shared util/jsonc (#808)
fix(opencode,server): string-aware JSONC stripping via shared util/jsonc (#806)

opencode.jsonc/kilo.jsonc with URLs in string values (e.g. "$schema":
"https://opencode.ai/config.json") were corrupted by the adapter's naive
stripJsonComments regex (/\/\/.*$/gm eats everything after "https:"),
so readSettings() returned null and ctx doctor emitted the false
"[FAIL] Plugin configuration: Could not read opencode.json or
opencode.jsonc".

- add src/util/jsonc.ts: two-pass string-aware comment + trailing-comma
  stripping and tolerant parseJsonc (byte-identical to the #787-reviewed
  implementation so the branches merge cleanly)
- opencode adapter: drop the naive regex stripper (introduced in 7189ed6
  to avoid a jsonc-parser dependency; the shared util keeps that
  property — zero imports, esbuild inlines it), route through the util
- server.ts: drop its local copy whose trailing-comma regex corrupted
  commas inside string values; import the shared util
- tests: URL-bearing opencode.jsonc/kilo.jsonc through the public
  adapter API, in-string comma regression, escaped quotes, CRLF, block
  comments with URLs, trailing commas, plain-JSON passthrough

Verified end-to-end on real OpenCode 1.17.1: URL-bearing opencode.jsonc
parses, doctor reports PASS, plugin loads and captures session events.

Closes #806

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 17:31:37 +03:00
Ben YounesandClaude Opus 4.8 ed91326260 fix(server): canonicalize cacheRoot in healCacheMidSession via realpathSync for symlinked ~/.claude (#795) (#805)
* fix(server): canonicalize cacheRoot in healCacheMidSession via realpathSync for symlinked ~/.claude (#795)

When ~/.claude is a symlink to another volume, healCacheMidSession
computed cacheRoot via path.resolve (no symlink dereference) but the
plugin registry stores installPath as a physical path. The
startsWith guard rejected every entry, skipping the mid-session
cache heal entirely.

Fix: canonicalize cacheRoot with realpathSync (try/catch fallback)
before the traversal guard, matching the pattern already used in
cli.ts upgrade() and statuslineForward().

* fix(test): use realpathSync on installPath in symlink containment test

On macOS /var is a symlink to /private/var. fs.realpathSync(lexicalCacheRoot)
resolves ALL symlinks including the filesystem-level /var→/private/var, but
resolve(physicalInstallPath) stays on the non-canonical side, causing the
startsWith check to fail.

Apply realpathSync symmetrically to both sides of the comparison so the
canonical paths match regardless of platform-level symlinks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 14:07:55 +03:00
Mert Koseoglu 454db18ee0 Merge remote-tracking branch 'origin/main' into merge-main-to-next
# Conflicts:
#	stats.json
#	web/index.html
#	web/oss.html
#	web/worker.js
2026-06-09 21:26:35 +03:00
Ben Younes 813da2a6d0 fix(runtime): add liveness guard to resolveJavascriptRuntime for Homebrew Cellar ENOENT (#800) (#803)
* fix(runtime): add liveness guard to resolveJavascriptRuntime for Homebrew Cellar ENOENT (#800)

When process.execPath is a Homebrew Cellar path
(/opt/homebrew/Cellar/node/VERSION/bin/node), brew upgrade
plus brew cleanup deletes the old Cellar directory, leaving the
in-process execPath dangling.  The liveness guard falls back to
PATH-resolved node when the execPath no longer exists on disk.

Preserves the snap-node fix (#190): the snap wrapper binary
literally exists at its execPath, so the guard passes and the
path is returned verbatim (not collapsed to bare node).

- Add existsSync(execPath) check before returning execPath
- Existing snap-node + bun regression tests updated to mock
  existsSync returning true for their respective exec paths
- Two new tests covering:
  1. Stale Cellar path falls back to PATH node
  2. Stale Cellar + no PATH node returns null

* fix(test): cross-platform bun path mock in #800 Cellar ENOENT test

The existsSync mock only blocked Unix-style bun paths
(/.bun/bin/bun), but on Windows bunFallbackPaths returns
paths with backslashes (C:\Users\...\.bun\bin\bun.exe).
This caused bunExists() to find a real bun on the Windows CI
runner, making resolveJavascriptRuntime return the bun path
instead of 'node'.

Replace the single-platform .includes() check with a
cross-platform regex that matches both file separators
and the optional dot prefix on ~/.bun.
2026-06-09 21:23:15 +03:00
github-actions[bot] 535c367cd7 ci: update install stats 2026-06-09 12:55:31 +00:00
Mert Koseoglu ee8533a3e5 fix(landing): drop CI/CD reference — no CI/CD integration ships yet 2026-06-09 12:53:24 +03:00
github-actions[bot] be5db6142a ci: update install stats 2026-06-08 07:36:12 +00:00
Mert Koseoglu bfe07bee61 refactor(web): remove Enterprise section from oss.html
Per Mert directive 2026-06-07. Pulling the Enterprise card pending
clearer product story. Strips:
- L633-684 Context-as-a-Service block + 4-persona grid (EM, CISO,
  DevOps, developers) + design-partner CTA row
- ~50 lines of orphan CSS (.ent / .ent-feature / .persona-grid /
  .persona-card / .ent-final) — single-use, safe to drop

85 lines removed total. No other section references Enterprise.
2026-06-07 23:36:08 +03:00
Mert Koseoglu 9a93db7d91 refactor(insight): remove Enterprise section/page/menu
Per Mert directive 2026-06-07. Enterprise tier surface is being
pulled until the product story is clearer. Strips:

- src/routes/enterprise.tsx (full page: persona grid EM/CISO/DevOps,
  2x2 value props, design-partner mailto CTA)
- Enterprise nav entry + Building2 icon import from src/routes/__root.tsx
- Auto-regenerated src/routeTree.gen.ts without /enterprise route
2026-06-07 23:35:11 +03:00
Mert Koseoglu 2d40c7b82f refactor(web): remove Enterprise section from oss.html
Per Mert directive 2026-06-07. Pulling the Enterprise card pending
clearer product story. Strips:
- L633-684 Context-as-a-Service block + 4-persona grid (EM, CISO,
  DevOps, developers) + design-partner CTA row
- ~50 lines of orphan CSS (.ent / .ent-feature / .persona-grid /
  .persona-card / .ent-final) — single-use, safe to drop

85 lines removed total. No other section references Enterprise.
2026-06-07 23:34:41 +03:00
Mert Koseoglu 7fd3c99de6 feat(web): SEO + brand pass — Context Mode Insight, drop Analytics
Per Mert directive 2026-06-07:
  - Brand normalized to "Context Mode Insight" (singular, capital I).
    "Insights" plural → "Insight". 34 substitutions.
  - "Analytics" / "analytics" eliminated everywhere — 10 user-facing
    occurrences across index.html + oss.html, all → "Insight" /
    "insight".
  - twitter:creator @AcikAnaliz → @mksglu.

URL surface stays minimal: only / and /oss. Dropped the legacy
/insights alias from worker.js — no /insight or /insights route
exists. Canonical and og:url back to https://context-mode.com/.

Added baseline SEO files:
  - robots.txt (Allow all + sitemap pointer)
  - sitemap.xml (two URLs — / and /oss)
  - og:image meta points to /og-insight.png (asset still TODO,
    declared so the OG harvester knows what to expect)

Title trimmed for SERP fit:
  "Context Mode Insight — AI engineering signal at $20/seat" (56 ch)
2026-06-07 17:07:01 +03:00
Mert Koseoglu 1213d5a099 web(oss): redesign to mirror Insights landing — Wave hero, magazine width, no Blog
Adopt the full design language of web/index.html (the Insights paid
landing) so /oss reads as a visual sibling.

Treatment changes:
- Replace narrow .wrap (680px) with index.html's 1280px primary / 840px
  narrow width policy (web/oss.html:90-95).
- Adopt the full design-token block (--accent / --green / --orange /
  --purple / --rose / --night triplet + --serif/--sans/--mono families)
  from index.html (web/oss.html:65-83).
- Rewrite every chapter to use the kicker / .h2 / .rule / .lead /
  .body rhythm and the "§ NN · label" section-num pattern
  (web/oss.html:444 for §01 … web/oss.html:686 for §09).
- Hero adopts .hero / .hero-inner.wrap / .h1 italic-serif + .hero-stats
  + .hero-cta + .hero-tags structure from index.html
  (web/oss.html:417-444).
- Animated SVG WAVE behind the hero, three drifting layers in
  accent/green/purple gradients, prefers-reduced-motion honored
  (web/oss.html:124-138, 419-435).
- Trust strip rebuilt with .trust / .trust-headline / .trust-brands
  pattern (web/oss.html:158-167, 446-455).
- Bench grid moves to 4-up card layout with serif italic stat numerals
  (web/oss.html:194-202, 491-496 and 533-538).
- Hook list adopts left-accent layered rows (web/oss.html:205-212).
- Code block switches to dark night surface to match index.html chapter
  aesthetic (web/oss.html:214-220, 567-580).
- Security 2x2 card grid with green-accent left border
  (web/oss.html:241-251, 654-670).
- Enterprise dark card rebuilt to mirror index.html .final treatment:
  gradient night background, radial-gradient halos, .kicker overlay,
  inset persona cards, centered final CTA row
  (web/oss.html:268-307, 696-744).
- Footer adopts index.html .footer-q italic serif + .footer-links
  + .footer-addr layout (web/oss.html:312-318, 749-758).
- Sticky bottom CTA added pointing at the GitHub install URL
  (web/oss.html:321-340, 762-767).

Content removed per "Docs'u sil, docs linki de verme":
- Entire "Blog" chapter and its three mksg.lu/blog cards.
- No documentation/docs links anywhere on the page.

Content preserved verbatim: hero tagline, every stat number, NoLiMa
benchmark, gh issue list math, hook descriptions, /ctx-insight notes,
15-platform tag list, security claims, install commands, Cal.com +
mailto CTAs, MKSF LTD address line, mksg.lu credit.

Line count: 543 → 761 (delta driven by adopting the full design-system
stylesheet, not new content).
2026-06-07 17:07:01 +03:00
Mert Koseoglu fa402cd390 fix(landing): align FAQ chapter to centered-axis pattern matching pricing
Owner directive (2026-06-07): "layout u bozuyor biraz ortali oldugu icin,
pricing'de yaptigin gibi yap" — the FAQ chapter was the only chapter using
wrap-narrow (840px tight-center) while every other chapter uses wrap
(1280px) with an inline-centered intro block. The inconsistency broke
page rhythm.

Mirror the Pricing chapter pattern shipped in 48cfe06 (web/index.html
L461-468):
  - section uses regular .wrap container (1280px) instead of .wrap-narrow
  - intro block .rev: max-width:880px; margin:0 auto; text-align:center
  - .rule: margin-left:auto; margin-right:auto
  - .faq details list: max-width:840px; margin auto (preserves the
    comfortable reading width of wrap-narrow inside a centered column
    while the questions/answers stay left-aligned by default)

Also adds id="faq" to the chapter for anchor parity with id="pricing".

Files:
  - web/index.html L1292-1301 (FAQ intro block — was using wrap-narrow
    + no centering styles → now matches pricing's centered-axis pattern)
  - mirrors web/index.html L461-468 (pricing intro block — the
    canonical centered-axis treatment)

No content change. Visual treatment only — every <details> question +
answer body is byte-identical.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 4d6069adfc fix(landing): remove pricing deny-list + simplify peer-tier copy
Mert directive: "What this is not" deny-list section ("No SSO. No SOC 2
report. No on-prem option ...") removed entirely. The pricing chapter
also dropped the competitor-peer-tier callout ("Same band as Cursor
Pro, GitHub Copilot Business, Vercel Pro — the AI-dev-tool tier you
already budget for") which Mert flagged as unnecessary mention.

The remaining pricing chapter elements are now centered (kicker, H2,
rule, lead, card) so the chapter reads as one focused vertical block
instead of the prior left-headline + center-card asymmetry that broke
the page rhythm.

Also softened the SSO/SOC 2 FAQ answer:
  before: "If your buying process requires SSO or a SOC 2 report, run
          the OSS collector self-hosted (free, ELv2 source-available);
          we will revisit Enterprise after the first Series A."
  after:  "The OSS collector is source-available under ELv2 and can be
          run self-hosted if your buying process requires those
          controls."

The Series A reference removed (out of band for buyer-facing copy);
competitor mentions in the FAQ removed.

Net delta: 5 line removal in pricing chapter + 1 line FAQ rewrite.
The Linear / Notion / Jira mentions in the §Integrations chapter stay
— those are functional integration partners, not pricing peers.
2026-06-07 17:07:01 +03:00
Mert Koseoglu db80c615c1 fix(landing): retarget signup CTAs to platform.context-mode.com root
Wave PS (platform repo, commit d511924) deleted the /signup route
entirely. Card capture moved to Stripe-hosted Checkout via the OAuth
callback → /?signup=needs_checkout&… → POST /auth/signup-with-checkout
flow. Per Mert directive: "Bizim Platform'da /signup isminde bir
endpoint imiz bir Page'imiz yok ... Signup olmamalı."

Every CTA on this landing pointed at platform.context-mode.com/signup
which now returns 404 (route removed in routeTree.gen.ts). This commit
retargets all 11 references to the platform root:

- L39  JSON-LD offers.url
- L441 §01 chapter CTA
- L549 §02 chapter CTA
- L1166 §08 chapter CTA
- L1275 §09 chapter CTA
- L1308 pricing card CTA
- L1327 lead paragraph link
- L1396 FAQ answer link
- L1441 §10 chapter CTA
- L1459 footer micro-copy
- L1479 sticky bottom CTA

The platform root (https://platform.context-mode.com) renders the
WelcomeLanding component for unauthenticated visitors (Google + GitHub
OAuth buttons). After OAuth, the new-user path lands on Home with the
?signup=needs_checkout marker which kicks off Stripe Checkout.

No copy change beyond the URL — every "Start for $20 / seat" button
still says the same thing, just points one URL segment shorter.
2026-06-07 17:07:01 +03:00
Mert Koseoglu a71663eb94 verify(landing): owner-directive 2026-06-06 wave audit
Empty verify commit closing the 3-fix wave (waitlist removal,
trust strip alignment fix, pricing relocation).

=== File state ===
Line count: 1524 -> 1437 (delta -87)
<section open tags: 14 -> 13 (waitlist removed)
</section> close tags: 14 -> 13 (matched)

=== Forbidden strings (all 0) ===
waitlist (case-insensitive): 0
hand-onboarding: 0
guided rollout: 0
seat_count: 0
#waitlist anchors: 0
Free Team: 0
private beta: 0
Beta (word boundary): 0
MIT: 0

=== Required strings ===
$20: 28 (target >=8) PASS
222: 12; "222 patterns": 10 (target >=5) PASS
platform.context-mode.com/signup: 17 (target >=2) PASS
ELv2: 2 PASS
id="pricing": 1

=== Storytelling order verified ===
L439: <section class="trust">
L461: <section class="chapter" id="pricing">   <- moved here
L501: <p class="section-num">§ 01 · the problem</p>
Trust strip -> Pricing -> §01 Problem -> ... -> §10 Security
  -> FAQ -> Footer. No #waitlist dead anchors anywhere.

=== Trust strip fix (Slice 2) ===
.trust-grid changed from grid-template-columns:auto 1fr (which
forced 20 brand spans into a tall right-side column) to
display:flex;flex-direction:column;gap:20px. Headline now stacks
above the brands row; brands wrap horizontally via existing
flex-wrap:wrap.

Wave commits:
  21c373e remove waitlist section entirely
  bde1e0a fix trust strip alignment
  5390c69 move pricing chapter to position 2
2026-06-07 17:07:01 +03:00
Mert Koseoglu 934523d336 feat(landing): move pricing chapter to position 2 (after trust strip)
Owner directive 2026-06-06: pricing needs prioritized work — make
it more prominent. $20/seat is the value claim; burying it nine
chapters deep was wrong for a self-serve funnel.

Option A (per the directive): relocate the entire <section
id="pricing"> block to immediately after the trust strip, before
the PROBLEM chapter (§01). Visitors now see the price band within
the first scroll after they see the hero + trust signal.

- Cut <section id="pricing"> block (36 lines incl card, deny-list)
  from between SECURITY (§10) and FAQ
- Paste it directly after the trust strip's closing </section>,
  before the PROBLEM (§01) chapter
- Drop the "§ 11 · pricing" section-num prefix — pricing is no
  longer a numbered chapter in the storytelling sequence; it is
  a top-funnel anchor right after the trust signal. The remaining
  §01-§10 numbered chapters keep their ordering. FAQ's existing
  "§ 12 · faq" label is preserved (pre-existing pattern, not
  touched by this wave)
- pricing-card, pricing-cta, pricing-fine, pricing-deny-list CSS
  classes are untouched and continue to render the card identically
- The #pricing anchor still resolves; in-page links to #pricing
  (none currently exist in this file) would still jump correctly

Storytelling rhythm post-move:
  Hero -> Trust strip -> Pricing (NEW slot) -> Problem (§01) ->
  Solution (§02) -> ... -> Security (§10) -> FAQ -> Footer

Verify: section count unchanged (13 open / 13 close); id="pricing"
appears once; pricing block precedes the §01 problem chapter.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 9d0860f423 fix(landing): unbreak trust strip alignment (vertical stack)
Owner reported (2026-06-06) the trust strip rendered with 20
company names stacked in a tall right-side column instead of a
horizontal wrap-row.

Root cause: .trust-grid used display:grid with grid-template-columns:
auto 1fr. The first column (auto) sized to its content — the
trust-headline block contains a long sentence + <br> + lead sentence,
so 'auto' computed to ~75% of viewport width. The second column
(1fr) got only the leftover narrow strip, forcing 20 brand spans
to wrap one-per-line vertically. The 900px media-query breakpoint
hid the bug on small screens but not desktop.

Fix (surgical, no redesign):
- .trust-grid: display:grid;grid-template-columns:auto 1fr;gap:48px
  -> display:flex;flex-direction:column;gap:20px
- .trust-headline: add max-width:880px so headline doesn't span
  the full container on ultrawide
- .trust-brands: add align-items:center for vertical rhythm with
  the row above (flex-wrap:wrap was already correct)
- Replace 900px breakpoint with a 600px breakpoint that just
  tightens brand gap/font — desktop is now correct, mobile too

Result: headline renders on top (max-width 880px), brands wrap
underneath as a horizontal row that flows naturally across 1-5
visual rows depending on viewport width.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 351c7f4835 feat(landing): remove waitlist section entirely
Owner directive 2026-06-06: kill waitlist completely (was demoted
to hand-onboarding in 61137a2 — now gone). Self-serve at
platform.context-mode.com is the only path.

- Delete <section id="waitlist"> block (62 lines incl form, fields,
  seat_count, bullets, web3forms POST handler, guided rollout copy)
- Delete .waitlist-* CSS block (22 lines: form, field, label, input,
  radio-group, bullets)
- Replace hero secondary CTA "Or join the waitlist for hand-onboarding"
  with "Or run the OSS plugin locally" -> github.com/mksglu/context-mode
- Replace four chapter primary CTAs "Join the waitlist" with
  "Start for $20 / seat" -> platform.context-mode.com/signup
- Replace two chapter secondary CTAs alongside docs/integrations links
- Replace footer final-cta "Join the waitlist" with signup CTA
- Delete <hr class="sep"> separator that preceded waitlist
- Web3forms endpoint remains accessible — landing no longer posts to it

Verify: grep -ic waitlist = 0; section count 14 -> 13; line count
1524 -> 1438 (-86 net). All #waitlist anchors removed (0 dead links).
2026-06-07 17:07:01 +03:00
Mert Koseoglu 9de2291aa3 verify(landing): PRD §9 checklist complete
PRD docs/prds/2026-06-pricing/02-landing-page-update.md §9
verification checklist - all green.

Forbidden strings (each must be 0 unless noted):
  "\$0":             0
  private beta:      0
  design partner:    0
  design-partner:    0
  Team tier:         0
  Enterprise tier:   0
  free Team:         0
  annual discount:   0
  trial:             6 - ALL negation context ("no trial", "There
                       is no Insights trial") - PRD §9 line "No
                       trial anywhere" refers to positive offer,
                       not the affirmative pricing disclaimer
                       which the PRD itself mandates in §4.8 +
                       §4.9. Verified by reading every match.
  volume discount:   3 - ALL negation context ("No volume
                       discount.", "no volume discount,") -
                       same logic; this IS the spec.

Required strings (minimum thresholds from task slice 12):
  \$20:                23 (>= 8 by Slice 6)            PASS
  222:                10                              PASS
  14 adapters:        2                               PASS
  13 MCP tools:       5                               PASS
  signup URL:         11 (>= 2 by Slice 9)            PASS
  220 patterns:       0                               PASS
  10 adapters:        0                               PASS

Sites resolved against PRD §2 audit table (15 rows):
  1  L6 title:                  enterprise -> \$20/seat              Slice 1
  2  L7 meta description:       220 -> 222 + \$20/seat              Slice 1
  3  L14 og:description:        220 -> 222 + OSS/Platform tagline   Slice 1
  4  L21 twitter:description:   220 -> 222, 10 -> 14, +\$20          Slice 1
  5  L32 JSON-LD description:   220 -> 222 + price + Offer fragment Slice 1
  6  L382-405 hero:             price anchor + \$20 primary CTA      Slice 2
  7  L437 lead:                 already aligned (seat license)      n/a
  8  L856 H2:                   220 -> 222 patterns                 Slice 3
  9  L999 adapters H2:          10 -> 14 adapters, 3 paradigms      Slice 4
  10 L1194 waitlist H2:         "private beta" -> "guided rollout"  Slice 7
  11 L1228-1232 monthly_budget: removed, seat_count input added    Slice 7
  12 L1250-1251 free Team:      bullet removed + replaced           Slice 7
  13 L1276 private beta:        FAQ "live yet" pair deleted         Slice 8
  14 L1335 footer micro-copy:   "private beta" -> "\$20 / seat"      Slice 10
  15 L1265+ FAQ audit:          3 stale removed, 4 pricing added    Slice 8

Additional out-of-PRD audit fixes:
  - L449 trust strip "currently in private beta" -> Pro \$20/seat   Slice 7
  - L1394 FAQ pattern count 219 -> 222 + 10 -> 14 adapters         Slice 8
  - L500 Solution gtm-strip waitlist CTA -> \$20 signup             Slice 11
  - L546 + L1091 + L1235 chapter gtm-strips: all -> \$20 signup     Slice 4, 6, 11

11 atomic commits land before this audit commit.
2026-06-07 17:07:01 +03:00
Mert Koseoglu eab7f35851 copy(landing): close analytics-layer chapter with OSS/Platform split sentence
Append canonical OSS/Platform split paragraph at the end of the
"Insights - the analytics layer" chapter body, before the gtm-strip
CTA per PRD §4.3:

  "The OSS plugin stays free forever - it is the collector. The
  Platform is where your team sees what's happening. Pro tier is a
  flat \$20 per seat per month. No tiers, no trial, no surprise
  metering."

This is the canonical sentence Mert can cite in any future copy
review. New .chapter-close CSS hook (--bg-alt panel, --accent
left border, --accent-dark emphasis) so the line reads as a closing
emphasis without breaking the section's existing rhythm.

Replace the lingering "Join the waitlist" gtm-strip CTA at the end
of this chapter with "Start for \$20 / seat" so the visual primary
path stays consistent with hero / pricing / FAQ.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 410b7eecb6 copy(landing): footer micro-copy reflects $20/seat self-serve model
L1437 before:
  "Private beta . onboarding 5 design-partner orgs . free Team-tier
  access during the design phase . shape the patterns we ship next."

After:
  "Pro \$20 / seat / month . platform.context-mode.com . OSS
  collector free forever."

Per PRD §4.11. Final forbidden-string elimination at the footer
level. Adds an underlined link wrapper on platform.context-mode.com
so the line itself converts.
2026-06-07 17:07:01 +03:00
Mert Koseoglu aef64b0d2a feat(landing): add sticky bottom CTA that reveals after 80vh scroll
The page is long (1.5K+ lines, multi-screen scroll). Persistent
bottom-of-viewport CTA improves conversion without breaking chapter
rhythm per PRD §4.10.

HTML: fixed-position bar appended before </body> with:
  - "Pro \$20 / seat / month. No tiers, no trial, no surprise bills."
  - "Start ->" button to platform.context-mode.com/signup

CSS in existing <style> block using available vars (--bg-alt for
panel, --border for top-edge, --text/--text-2 typography,
--accent-dark hover). No --bg-elevated -> --bg-alt instead.
translateY(100%) initial state, .visible toggles to translateY(0)
with 350ms ease transition. 640px breakpoint stacks vertical.

JS: passive scroll listener flips .visible after scrollY exceeds
80vh. aria-hidden flips in sync so screen readers ignore the bar
until it materialises.
2026-06-07 17:07:01 +03:00
Mert Koseoglu acc7005c64 copy(landing): rebuild FAQ for $20/seat pricing model
Remove 3 stale FAQ pairs (each containing "private beta", "design
partner", "free Team-tier", or "join the waitlist for design-partner
inquiries"):
  - "Is Insights live yet? How do I get in?"
  - "On-prem option?" (design-partner inquiries)
  - "What other Solutions are on the roadmap?" (design partners
    welcome) - content folded into "How does Insights relate to
    Context Mode Platform?" so Audit/Risk Score is still surfaced

Add 4 new pricing-aligned FAQ pairs at the top per PRD §4.9:
  - How much does Insights cost?
  - Can I try it free?
  - What is your refund policy?
  - Do you offer SSO / SAML / SOC 2?

Also fix the "How are the patterns built?" answer which had stale
counts:
  - 219 patterns -> 222 patterns (matches catalog)
  - 8 categories -> 9 categories (cost category included)
  - 10 adapters (Kimi listed) -> 14 adapters (rebuilt list matches
    Slice 4 adapter chapter)
  - 15 platform integrations on OSS side -> 16 (configs/ directory
    count)

FAQ closing gtm-strip CTA: "Still have questions? Join the waitlist"
-> "Start for \$20 / seat" pointing at signup. Hand-onboarding orgs
still reach the waitlist via the demoted Slice 7 form upstream.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 7bbf04a9cc copy(landing): demote waitlist to hand-onboarding path
Per PRD §4.7 - waitlist stays for orgs that want guided rollout, but
the language drops every "private beta" and "free Team-tier" claim:

- H2: "Insights is in private beta." -> "Want a guided rollout? Tell
  us about your team."
- Lead: rewritten to point self-serve customers to
  platform.context-mode.com/signup and frame this form as
  hand-onboarding only
- monthly_budget radio group removed entirely (price is fixed
  \$20/seat x N - no budget band to guess) - replaced with
  seat_count number input (min 1, max 500, placeholder "e.g. 47")
- "No card required... 5 design-partner orgs" -> "We will reply
  within 24 hours"
- "Early access" bullet -> "Guided rollout" bullet
- "Free Team-tier during design phase" bullet -> "Same Pro tier,
  same price" bullet (\$20/seat from day one, cancel via Stripe)
- Section-num "11" -> "12" (pricing took the prior 11 slot)

Also fix trust strip L449 stale "currently in private beta" copy to
match the new self-serve framing - this site is not called out in
PRD audit table but it carried the forbidden "private beta" string.

Form backend unchanged - still POSTs to the same web3forms endpoint.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 737089e29f feat(landing): insert Pricing chapter between Roles and Waitlist
New section #pricing per PRD §4.8:
- "One tier. Twenty dollars per seat. Predictable." H2
- Pricing card: $20/seat/mo, 8 feature bullets (222 patterns, 14
  adapters, 90-day retention, persona views, etc.), CTA to
  platform.context-mode.com/signup, fine print on no annual/volume/
  trial/free
- Deny list: "What this is not" - no SSO, no SOC 2, no on-prem, no
  dedicated support. Revisit Enterprise after Series A.

CSS inline in existing <style> block using established vars:
--border, --border-light, --bg-alt (no --bg-elevated exists), --bg-warm
for deny list, --text/--text-2/--text-3 typography, --mono/--serif
fonts, --accent-dark hover. Mobile breakpoint at 640px shrinks card
padding + price font.

Replace prior "Join the waitlist" gtm-strip CTA on Roles section with
"Start for \$20 / seat" so Roles -> Pricing flows visually toward the
new primary path.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 803e1d2718 copy(landing): add persona price callouts to CTO + FinOps cards
Ground abstract pricing in concrete persona numbers:
- Sarah (CTO) ROI card: "Org pays 47 x \$20 = \$940 / month. Renewal
  is a Stripe quantity update, not a procurement event."
- Sophia (FinOps) cost card: "The \$50K/mo AI line item now has a
  sibling Platform line: \$940/mo for visibility into the other \$50K."

47-engineer reference org math (47 x \$20 = \$940) becomes the anchor
the rest of the page can cite. New .persona-price-callout CSS using
--accent / --accent-light / --accent-dark vars.

Per PRD §4.4. Bill/Ekrem in PRD map to existing Sarah/Sophia personas.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 48840523e1 copy(landing): bring adapter chapter to 14 adapters across 3 paradigms
Add 5 cards (alphabetical within paradigm groups):
  json-stdio (8):  Claude Code, Codex, Cursor, Gemini CLI,
                   JetBrains Copilot, Kiro, Qwen Code, VS Code Copilot
  ts-plugin (3):   Kilo, OpenClaw, OpenCode
  mcp-only (3):    Antigravity, Pi, Zed

Remove Kimi card (not in canonical 14 per PRD §4.6 list). Sources
verified against src/adapters/ + configs/ inventory. Adapter-paradigm
.mcp CSS class already exists at L303 - no new style needed.

Update hero-sub "10 more AI assistants" -> "9 more" and hero-stat
"10" -> "14" to match. Update chapter lead to "14 AI assistants via
three paradigms". Replace waitlist CTA in gtm-strip with $20 signup
CTA so the chapter's call-to-action matches the new hero primary.

Per PRD §4.6.
2026-06-07 17:07:01 +03:00
Mert Koseoglu ccae1c66cd copy(landing): bump pattern count 220 -> 222 in every claim
Six sites: hero-sub, hero-stat, analytics-layer lead, Engine step,
pattern chapter H2, Patterns metric. Wave N3 audit confirms 222
patterns at org scope (vs 37 local). Per PRD §4.5.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 981ea9076a copy(landing): add hero price anchor + primary CTA to $20 signup
- Insert hero-price-anchor under hero-sub: "OSS collects. Platform understands. $20 / seat / month."
- Primary CTA: "Join the waitlist" -> "Start for $20 / seat" -> platform.context-mode.com/signup
- Secondary CTA: "See the personas" -> "Or join the waitlist for hand-onboarding"
- New .hero-price-anchor CSS using existing --accent-light / --accent-dark / --mono vars

Per PRD §4.2. Waitlist demoted to secondary path for hand-onboarding orgs.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 9c14445b02 copy(landing): align meta + SEO header with $20/seat pricing model
- Title: "Enterprise AI engineering observability" -> "$20/seat AI engineering analytics"
- Meta description: 220 -> 222 patterns + "Pro $20/seat/month"
- og:title + og:description: same delta + OSS/Platform split tagline
- twitter:title + twitter:description: 220 -> 222, 10 -> 14 adapters, price added
- JSON-LD description: 220 -> 222 + price callout
- JSON-LD: NEW Offer fragment (price 20.00 USD, InStock, signup URL)

Per PRD docs/prds/2026-06-pricing/02-landing-page-update.md §4.1.
2026-06-07 17:07:01 +03:00
github-actions[bot] f8c66ee94b ci: update install stats 2026-06-07 17:07:01 +03:00
github-actions[bot] 405108e1cd ci: update install stats 2026-06-07 17:07:01 +03:00
github-actions[bot] 0b83b983ea ci: update install stats 2026-06-07 17:07:01 +03:00
github-actions[bot] e5d40d6cdb ci: update install stats 2026-06-07 17:07:01 +03:00
github-actions[bot] 7f8f7890e4 ci: update install stats 2026-06-07 17:07:01 +03:00
github-actions[bot] e0c25eb999 ci: update install stats 2026-06-07 17:07:01 +03:00
github-actions[bot] 47ed8a2a13 ci: update install stats 2026-06-07 17:07:01 +03:00
Mert Koseoglu 40f8bfe101 fix(web): swap landing filenames so / serves Insights and /oss serves OSS
Cloudflare Workers Builds auto-deploy did not honour run_worker_first
(likely an older wrangler version on the build runner), so worker.js
never executed and plain asset routing took over. That gave us:
  /        -> index.html (OSS content) -- wrong
  /oss     -> 404
  /insights -> insights.html (Insights content) -- wrong place

Swap the filenames so plain asset routing alone produces the correct
URLs:
  web/index.html = Insights landing  -> served at /
  web/oss.html   = OSS landing       -> served at /oss

worker.js is updated to match the new filenames so the routing stays
consistent whenever run_worker_first does kick in.
2026-06-07 17:07:01 +03:00
Mert Koseoglu f2f5de2979 fix(web): pin wrangler name to context-mode + add account_id
The production Worker is named "context-mode" in the Cloudflare
dashboard. wrangler.jsonc said "context-mode-web" which caused
manual `npx wrangler deploy` runs to target a separate Worker
that had no routes bound.

account_id pins the deploy to the correct account so wrangler
does not prompt or pick the wrong one in CI.

Cloudflare Workers Builds appears to override the name from the
dashboard either way (this is how the broken auto-deploy still
landed on the right Worker), but aligning the source removes the
confusion and lets `npx wrangler deploy` from the web/ directory
target the right Worker without flags.
2026-06-07 17:07:01 +03:00
Mert Koseoglu 16088526a2 fix(web): stop 307 redirect loop on context-mode.com
Workers Static Assets parsed web/_redirects and ran its 200 rewrite
rules as 307 redirects, looping / and /oss into /insights forever.
worker.js already routes via env.ASSETS.fetch, so _redirects was
both redundant and broken.

run_worker_first ensures worker.js takes precedence over asset
matching (otherwise / served index.html before reaching the router).
html_handling: "none" disables .html canonicalization that turned
/index.html into a 307 back to /.

Verified after manual wrangler deploy: /, /oss, /insights all return
200 with correct content.
2026-06-07 17:07:01 +03:00
Ken JoandOmX 1df5d3ca93 Fix mobile overflow on Insights persona cards (#772)
Prevent persona cards from overflowing on mobile

The live Insights landing uses long tool-call and pattern identifiers inside grid cards. Mobile one-column grids still kept min-content widths, so persona content pushed beyond the viewport and duplicated CSS quotes made the first question look broken.

Constraint: / and /insights route to web/insights.html through the Workers router.

Rejected: Copying live HTML into web/index.html | /oss uses index.html, while the broken live route is served from insights.html.

Confidence: high

Scope-risk: narrow

Directive: Keep mobile grid columns as minmax(0, 1fr) when cards contain long code-like tokens.

Tested: Playwright mobile render at 320, 375, 390, and 430 px; document/body width matched viewport and persona cards/tool calls stayed within card bounds. Copilot review follow-up kept persona calls accessible with overflow-x:auto and removed non-standard word-break usage.

Not-tested: Production deploy; this commit only updates the source file.

Co-authored-by: OmX <omx@oh-my-codex.dev>
2026-06-07 17:07:01 +03:00
Mert Koseoglu e935058b76 feat(web): unify Context Mode (/oss) + Insights Solution (/) under one Workers router
- web/insights.html added (moved from context-mode-platform repo) — GTM landing for Context Mode Platform · Insights, the first managed Solution
- web/worker.js + web/wrangler.jsonc: minimal Cloudflare Workers router
  - / and /insights → insights.html (Insights Solution — primary GTM)
  - /oss → index.html (the OSS plugin landing)
- web/_redirects: Cloudflare Pages fallback (same semantics)
- web/index.html: hero tag → / (cross-link from OSS landing to Insights Solution)

Brand:
- Context Mode = the open-source plugin (ELv2). Lives at /oss.
- Context Mode Platform = the managed Solutions umbrella. First Solution = Insights, lives at /.

Deploy: npx wrangler deploy from web/ directory.
2026-06-07 17:07:01 +03:00
github-actions[bot] b4d4797fad ci: update install stats 2026-06-07 17:07:01 +03:00
github-actions[bot] 29e80a6b3b ci: update server.bundle.mjs, cli.bundle.mjs, session hook & security bundles 2026-06-07 17:07:01 +03:00
github-actions[bot] c8508092a6 ci: update install stats 2026-06-07 07:20:10 +00:00
Mert Koseoglu e060e07e23 web(oss): redesign to mirror Insights landing — Wave hero, magazine width, no Blog
Adopt the full design language of web/index.html (the Insights paid
landing) so /oss reads as a visual sibling.

Treatment changes:
- Replace narrow .wrap (680px) with index.html's 1280px primary / 840px
  narrow width policy (web/oss.html:90-95).
- Adopt the full design-token block (--accent / --green / --orange /
  --purple / --rose / --night triplet + --serif/--sans/--mono families)
  from index.html (web/oss.html:65-83).
- Rewrite every chapter to use the kicker / .h2 / .rule / .lead /
  .body rhythm and the "§ NN · label" section-num pattern
  (web/oss.html:444 for §01 … web/oss.html:686 for §09).
- Hero adopts .hero / .hero-inner.wrap / .h1 italic-serif + .hero-stats
  + .hero-cta + .hero-tags structure from index.html
  (web/oss.html:417-444).
- Animated SVG WAVE behind the hero, three drifting layers in
  accent/green/purple gradients, prefers-reduced-motion honored
  (web/oss.html:124-138, 419-435).
- Trust strip rebuilt with .trust / .trust-headline / .trust-brands
  pattern (web/oss.html:158-167, 446-455).
- Bench grid moves to 4-up card layout with serif italic stat numerals
  (web/oss.html:194-202, 491-496 and 533-538).
- Hook list adopts left-accent layered rows (web/oss.html:205-212).
- Code block switches to dark night surface to match index.html chapter
  aesthetic (web/oss.html:214-220, 567-580).
- Security 2x2 card grid with green-accent left border
  (web/oss.html:241-251, 654-670).
- Enterprise dark card rebuilt to mirror index.html .final treatment:
  gradient night background, radial-gradient halos, .kicker overlay,
  inset persona cards, centered final CTA row
  (web/oss.html:268-307, 696-744).
- Footer adopts index.html .footer-q italic serif + .footer-links
  + .footer-addr layout (web/oss.html:312-318, 749-758).
- Sticky bottom CTA added pointing at the GitHub install URL
  (web/oss.html:321-340, 762-767).

Content removed per "Docs'u sil, docs linki de verme":
- Entire "Blog" chapter and its three mksg.lu/blog cards.
- No documentation/docs links anywhere on the page.

Content preserved verbatim: hero tagline, every stat number, NoLiMa
benchmark, gh issue list math, hook descriptions, /ctx-insight notes,
15-platform tag list, security claims, install commands, Cal.com +
mailto CTAs, MKSF LTD address line, mksg.lu credit.

Line count: 543 → 761 (delta driven by adopting the full design-system
stylesheet, not new content).
2026-06-07 00:38:24 +03:00
Mert Koseoglu e50affe1ba fix(landing): align FAQ chapter to centered-axis pattern matching pricing
Owner directive (2026-06-07): "layout u bozuyor biraz ortali oldugu icin,
pricing'de yaptigin gibi yap" — the FAQ chapter was the only chapter using
wrap-narrow (840px tight-center) while every other chapter uses wrap
(1280px) with an inline-centered intro block. The inconsistency broke
page rhythm.

Mirror the Pricing chapter pattern shipped in 48cfe06 (web/index.html
L461-468):
  - section uses regular .wrap container (1280px) instead of .wrap-narrow
  - intro block .rev: max-width:880px; margin:0 auto; text-align:center
  - .rule: margin-left:auto; margin-right:auto
  - .faq details list: max-width:840px; margin auto (preserves the
    comfortable reading width of wrap-narrow inside a centered column
    while the questions/answers stay left-aligned by default)

Also adds id="faq" to the chapter for anchor parity with id="pricing".

Files:
  - web/index.html L1292-1301 (FAQ intro block — was using wrap-narrow
    + no centering styles → now matches pricing's centered-axis pattern)
  - mirrors web/index.html L461-468 (pricing intro block — the
    canonical centered-axis treatment)

No content change. Visual treatment only — every <details> question +
answer body is byte-identical.
2026-06-07 00:36:20 +03:00
Mert Koseoglu 48cfe0612c fix(landing): remove pricing deny-list + simplify peer-tier copy
Mert directive: "What this is not" deny-list section ("No SSO. No SOC 2
report. No on-prem option ...") removed entirely. The pricing chapter
also dropped the competitor-peer-tier callout ("Same band as Cursor
Pro, GitHub Copilot Business, Vercel Pro — the AI-dev-tool tier you
already budget for") which Mert flagged as unnecessary mention.

The remaining pricing chapter elements are now centered (kicker, H2,
rule, lead, card) so the chapter reads as one focused vertical block
instead of the prior left-headline + center-card asymmetry that broke
the page rhythm.

Also softened the SSO/SOC 2 FAQ answer:
  before: "If your buying process requires SSO or a SOC 2 report, run
          the OSS collector self-hosted (free, ELv2 source-available);
          we will revisit Enterprise after the first Series A."
  after:  "The OSS collector is source-available under ELv2 and can be
          run self-hosted if your buying process requires those
          controls."

The Series A reference removed (out of band for buyer-facing copy);
competitor mentions in the FAQ removed.

Net delta: 5 line removal in pricing chapter + 1 line FAQ rewrite.
The Linear / Notion / Jira mentions in the §Integrations chapter stay
— those are functional integration partners, not pricing peers.
2026-06-07 00:20:15 +03:00
Mert Koseoglu ec5e96cf13 fix(landing): retarget signup CTAs to platform.context-mode.com root
Wave PS (platform repo, commit d511924) deleted the /signup route
entirely. Card capture moved to Stripe-hosted Checkout via the OAuth
callback → /?signup=needs_checkout&… → POST /auth/signup-with-checkout
flow. Per Mert directive: "Bizim Platform'da /signup isminde bir
endpoint imiz bir Page'imiz yok ... Signup olmamalı."

Every CTA on this landing pointed at platform.context-mode.com/signup
which now returns 404 (route removed in routeTree.gen.ts). This commit
retargets all 11 references to the platform root:

- L39  JSON-LD offers.url
- L441 §01 chapter CTA
- L549 §02 chapter CTA
- L1166 §08 chapter CTA
- L1275 §09 chapter CTA
- L1308 pricing card CTA
- L1327 lead paragraph link
- L1396 FAQ answer link
- L1441 §10 chapter CTA
- L1459 footer micro-copy
- L1479 sticky bottom CTA

The platform root (https://platform.context-mode.com) renders the
WelcomeLanding component for unauthenticated visitors (Google + GitHub
OAuth buttons). After OAuth, the new-user path lands on Home with the
?signup=needs_checkout marker which kicks off Stripe Checkout.

No copy change beyond the URL — every "Start for $20 / seat" button
still says the same thing, just points one URL segment shorter.
2026-06-06 22:41:22 +03:00