Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ jobs:
mkdir -p _site/status
cp landing/index.html _site/index.html
cp public/index.html _site/status/index.html
# Brand assets referenced by absolute URL from both pages (favicon,
# apple-touch-icon, 1200x630 og card). Served from the Pages root.
cp docs/assets/og.png docs/assets/favicon.svg docs/assets/apple-touch-icon.png _site/
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ npm-debug.log*

# Local backups the installer creates
.backup-*/

# Generated status page — built fresh at deploy (scripts/build-pages.mjs)
public/
11 changes: 8 additions & 3 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,14 @@ every intra-repo Markdown anchor (`#x` and `path.md#x`) against the target's rea
(GitHub-exact slugs — em-dashes yield `--`, never collapsed), killing the dead-anchor class;
and `checkRoadmap` fails when the ROADMAP's "Now" marker trails the shipped `package.json`
version. The two public pages
(`landing/index.html` + the `build-pages.mjs` status page) share one set of design tokens,
enforced for parity (plus non-empty changes list, no phantom webfont) by
`test/pages.test.js` — so neither the docs' numbers nor the site's look can silently drift.
(`landing/index.html` + the `build-pages.mjs` status page) derive from ONE color source —
`brand.json.colors` (full dark + light palettes), emitted as CSS by `src/brand.js`
(`rootTokensCss()`). `test/pages.test.js` enforces full-palette parity: every hex in
`brand.json` must appear on both surfaces, so the palette can't fork into "two palettes
claiming to be one" again (plus non-empty changes list, no phantom webfont, present
social/favicon metadata). `checkDiagrams` extends the same single-source rule to Mermaid —
every `%%{init` theme must carry the brand's ember + warm-black hexes — so neither the docs'
numbers nor the site's look can silently drift.

**Auto-release (`.github/workflows/bump.yml` + `scripts/bump.mjs`).** A push to `master`
runs `bump.mjs auto`: it releases only when a `feat`/`fix`/`perf`/breaking commit landed
Expand Down
63 changes: 61 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,65 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

- **Single design-token source.** `brand.json` gained a `colors` block (full dark +
light palettes) as the one source of the visual palette, plus `fonts` and `site`.
`src/brand.js` exposes it via `cssVars(scheme)` + `rootTokensCss()` pure helpers;
the generated status page (`scripts/build-pages.mjs`) now injects tokens from that
one source (and gains light mode), and `test/pages.test.js` enforces full-palette
parity — every dark and light hex in `brand.json` must appear on both public pages,
so the landing page and status page can no longer fork into two palettes claiming
to be one.
- **Landing page redesign.** Rebuilt `landing/index.html` on a Stat-Led structure:
the real shipped hero diagram is now embedded (inlined so it resolves in local
preview and at the deployed site root), the fake terminal chrome, placeholder
digit/glyph icons, and faux-live pulse dot are gone, capabilities use real inline
SVG icons in a hairline-divided layout instead of a uniform card grid, and the
sticky-nav blur is compositor-light. Light-mode accents are darkened to meet AA
contrast on the light paper.
- **Accessibility + design-system hygiene.** All accent/supplementary-text pairs on
both themes are now verified ≥4.5:1 (bumped `--faint` in dark + light, and light
`--brand`/`--ok`, at the single brand.json source). Border-radii are collapsed onto
a deliberate 3-level scale (`--radius-sm` / `--radius` / pill), so `forge uicheck
design` passes spacing-scale, radius-levels, and shadow-levels with a healthy
slop-distance. Focus rings appear instantly (no animated outline), motion is
transform/opacity-only under `prefers-reduced-motion`.

### Added

- **Social + icon metadata on both public pages.** The landing and generated status
pages now ship `og:image` / `twitter:image` (a 1200×630 brand card,
`docs/assets/og.png`, rasterized once via Chromium — an author artifact, not a
runtime dep), a favicon + apple-touch-icon (`docs/assets/favicon.svg` /
`apple-touch-icon.png`), and consistent `canonical` == `og:url`. The status page
gained a full Open Graph / Twitter / `SoftwareApplication` JSON-LD head; the deploy
workflow copies the brand assets to the Pages root so the absolute URLs resolve.
- **Brand-aligned status line.** `global/statusline.sh` now renders the exact brand
tokens (ember `#f26430`, warm-taupe greys) in 24-bit truecolor from a named palette
block, with a 256-color fallback when the terminal can't do truecolor. New
`test/statusline.test.js` smoke-tests the segments, the exact truecolor hexes, the
fallback, and graceful degradation on minimal input.
- **Mermaid theme-value guard.** `forge docs check`'s `checkDiagrams` now verifies each
`%%{init` block carries the brand's actual color values (ember + warm-black from
`brand.json`), not just that a theme directive is present — a diagram can no longer
declare a theme and still render off-brand. README leads with a `Start in 60 seconds`
block, and `ARCHITECTURE.md` documents `brand.json` as the single color source.

### Fixed

- **Status-page metrics were silently stale.** The `impact` and `saved` regexes in
`scripts/build-pages.mjs` no longer matched the current README, so those
"repo-sourced" numbers were really hardcoded fallbacks. Regexes fixed to parse the
README, and a non-match is now a hard build error (`mustMatch`) instead of a silent
fallback; the dead `claim` field is removed.
- **Generated status page no longer ships stale/leaky.** `public/index.html` is a
build artifact (regenerated at deploy), so it is now gitignored and dropped from
the npm `files` list — a stale committed copy (old version + a dev-branch name
leaked into a visible chip) can no longer be published in the tarball.
- **Landing → status link** now points at the absolute Pages URL, so it resolves in
local file preview instead of 404-ing on `./status/`.

## [0.17.0] - 2026-07-15

### Added
Expand All @@ -25,7 +84,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Added

- **Playwright interaction loop** — `forge uicheck interact <file-or-url>` drives the
page headless under `prefers-reduced-motion` and checks what it *does*
page headless under `prefers-reduced-motion` and checks what it _does_
(console-clean, keyboard-reachable, focus-visible, reduced-motion), where
`uicheck visual` only fingerprints what it paints. The verdict is recorded through
the ledger's cross-family-gated `behavioral` oracle (advisory by default;
Expand Down Expand Up @@ -55,7 +114,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
MAE. Advisory by default — routing keeps the rubric until a promotion is adopted
(`calibratedComplexity` mirrors `predictor.riskFor`). Zero deps, fully unit-tested.
- **Legacy-store retirement (`FORGE_LEDGER_ONLY`)** — the PCM ledger can now be the
*only* store. Since P1 it has been the convergent write store (dual-write) with a
_only_ store. Since P1 it has been the convergent write store (dual-write) with a
merged read (`ledger_read`); with `FORGE_LEDGER_ONLY=1` the legacy files
(`.forge/lessons/*.md`, recall/brain fact files) stop being written and every read
materializes from the ledger — cortex confirm/create/distill dedup against
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,21 @@ delivers them into every tool you use.
> **Status: beta.** The core (`init`, `sync`, `substrate`, `impact`, `ledger`, guards) is
> tested and in daily use; some flags may change before `1.0`.

## Start in 60 seconds

```bash
npm install -g @codewithjuber/forgekit # or: npm install -g github:CodeWithJuber/forgekit
forge init # emit every AI tool's native config from one source
forge doctor # verify providers, hooks, and MCP wiring
```

That's it — your agents now share one source of truth. The
[full quickstart](#60-second-quickstart) walks through the loop; [Commands](#commands)
lists everything `forge` can do.

## Contents

- [Start in 60 seconds](#start-in-60-seconds)
- [The problem](#the-problem)
- [How it works — the loop](#how-it-works--the-loop)
- [What you get](#what-you-get)
Expand Down
40 changes: 40 additions & 0 deletions brand.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,45 @@
"atlas": "code-graph (symbol/call index)",
"lean": "minimalism discipline",
"recall": "cross-session memory"
},
"site": {
"url": "https://codewithjuber.github.io/forgekit/",
"repo": "https://github.com/CodeWithJuber/forgekit"
},
"fonts": {
"sans": "system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif",
"mono": "ui-monospace, \"SF Mono\", SFMono-Regular, Menlo, Consolas, monospace"
},
"colors": {
"dark": {
"bg": "#171310",
"bg-2": "#201a15",
"panel": "#201a15",
"panel-2": "#272019",
"text": "#f2ede7",
"muted": "#a99e90",
"faint": "#8a7d6d",
"line": "#372c22",
"line-strong": "#4a3b2e",
"brand": "#f26430",
"brand-2": "#f7a072",
"ok": "#67e8a5",
"shadow": "0 24px 64px rgba(23, 19, 16, 0.56)"
},
"light": {
"bg": "#f7f3ed",
"bg-2": "#fffdf9",
"panel": "#fffdf9",
"panel-2": "#efe7db",
"text": "#201a15",
"muted": "#6b5f50",
"faint": "#7e7161",
"line": "#e2d6c4",
"line-strong": "#cbbba3",
"brand": "#ba4b1e",
"brand-2": "#b8481c",
"ok": "#1b7e48",
"shadow": "0 24px 64px rgba(32, 26, 21, 0.12)"
}
}
}
Binary file added docs/assets/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions docs/assets/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/og.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions docs/assets/og.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 18 additions & 6 deletions global/statusline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,27 @@ fi
[ -n "${dir:-}" ] || dir="$PWD"
short="${dir/#$HOME/\~}"

# Palette (256-color): muted structure, one ember accent, green/red reserved for the diff.
# Palette — the exact forgekit brand tokens (brand.json.colors.dark) rendered in
# 24-bit truecolor so the ember and warm-taupe greys are on-brand, not the nearest
# off-brand xterm-256 index. Named block; one ember accent, green/red only for the
# diff. Falls back to the closest 256-color indices when the terminal can't do
# truecolor (COLORTERM unset / not 24-bit), so it degrades instead of mis-rendering.
e=$(printf '\033')
R="${e}[0m"
BOLD="${e}[1m"
DIM="${e}[38;5;245m"
MUTED="${e}[38;5;247m"
EMBER="${e}[38;5;209m"
GREEN="${e}[38;5;114m"
RED="${e}[38;5;174m"
if [[ "${COLORTERM:-}" == *truecolor* || "${COLORTERM:-}" == *24bit* ]]; then
DIM="${e}[38;2;125;114;99m" # faint #7d7263 warm taupe
MUTED="${e}[38;2;169;158;144m" # muted #a99e90
EMBER="${e}[38;2;242;100;48m" # brand #f26430 ember
GREEN="${e}[38;2;103;232;165m" # ok #67e8a5
RED="${e}[38;2;224;96;90m" # diff-removed (warm red, distinct from ember)
else
DIM="${e}[38;5;245m"
MUTED="${e}[38;5;247m"
EMBER="${e}[38;5;209m"
GREEN="${e}[38;5;114m"
RED="${e}[38;5;174m"
fi
SEP=" ${DIM}·${R} "

# dir
Expand Down
Loading
Loading