Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
d903a94
chore(quality): add coverage, dead-code, commit-message and secret gates
naashw Aug 22, 2026
2173a67
chore(quality): parallelise the pre-push gates and scope tests to the…
naashw Aug 22, 2026
407da1d
Merge pull request #86 from getCodesema/chore/quality-gates
naashw Aug 22, 2026
cad5c6b
chore(quality): pin out the advised transitives and gate on bun audit
naashw Aug 22, 2026
d96f3fa
Merge pull request #87 from getCodesema/chore/audit-gate
naashw Aug 22, 2026
60b3705
feat(web): add tailwind v4 theme foundation
cincrement Aug 24, 2026
04e123d
feat(forge): widen the merge request contract with enriched nullable …
cincrement Aug 24, 2026
c8dae3a
feat(web): serve forge issues and load them per project
cincrement Aug 24, 2026
5cbc24b
feat(web): add the shared merge request card and metadata rail
cincrement Aug 24, 2026
2bf976c
fix(forge): bound the merge request list, its pages and its output bu…
cincrement Aug 24, 2026
a045b67
feat(web): add the issue radar screen to the workspace focus zone
cincrement Aug 24, 2026
1337e44
fix(web): keep the merge request list outcome instead of a bare array
cincrement Aug 24, 2026
fccb9e2
chore: release 0.14.0
cincrement Aug 24, 2026
46b727e
fix(forge): drop the commits field that exceeds github's graphql node…
cincrement Aug 24, 2026
7078696
fix(web): make the accordion count and empty states follow the active…
cincrement Aug 24, 2026
766d897
docs: say why the commit count is not read from github
cincrement Aug 24, 2026
38fae84
refactor(web): rename the board screen and its vocabulary to forge board
Aug 24, 2026
4ca9d3f
feat(forge): carry each label's colour through the contract
Aug 24, 2026
8eaccd8
feat(web): render labels with their forge colour and a contrast-safe …
Aug 24, 2026
1857783
feat(web): lay the board out in four columns with resizable panels
Aug 24, 2026
b271902
chore(web): reword the comments that used an em dash
Aug 24, 2026
0f38a29
feat(web): move sort, filters and labels into the controls panel
Aug 24, 2026
1daf59d
feat(forge): let both lists be read beyond the open state
Aug 24, 2026
d3808f0
feat(web): tighten the list to the target density
Aug 24, 2026
1e9f200
feat(web): give the three secondary hues a dark counterpart
Aug 24, 2026
1c68a9f
feat(web): draw every icon from the lucide set
Aug 24, 2026
3147138
feat(web): replace the last text glyph in the controls panel
Aug 24, 2026
b8fe1ec
test(web): pin the collapse glyph
Aug 24, 2026
60263fa
feat(web): build the detail panel and its metadata rail
Aug 24, 2026
7027ff1
feat(web): render the body markdown with an explicit sanitiser
Aug 24, 2026
2327183
docs: record the four-column board in the changelog
Aug 24, 2026
1d62080
feat: serve the web ui from the vite dev server in dev
Aug 24, 2026
7af97d0
fix(web): bound the markdown render by length and by shape
Aug 24, 2026
acb00f2
docs: record the markdown body and its bounded render
Aug 24, 2026
972a649
chore(forge): drop the label type re-export nothing imports
Aug 24, 2026
2a1cd1d
feat(web): give the menu its icons and drop its row borders
Aug 24, 2026
ce12cfd
fix(web): neutralise the native button border in the menu
Aug 24, 2026
f9943c5
fix(web): tint the active menu row with the accent
Aug 24, 2026
4d13597
feat(web): merge the menu into the board rail, three columns
Aug 24, 2026
6ffb8d2
feat(web): set the body scale and add motion and shadow tokens
Aug 24, 2026
cd16233
fix(web): make the left rail permanent so the menu never moves
Aug 24, 2026
159adbd
feat(web): wire the merge request state filter end to end
Aug 24, 2026
54577eb
feat(web): add a coarse keyboard step and animate the rail collapse
Aug 24, 2026
c2874bc
feat(web): give the detail panel a three-band sticky header
Aug 24, 2026
f669253
feat(web): conversations column, composer and event card primitives
Aug 24, 2026
19ed37e
feat(web): changes panel with its file list and inline diffs
Aug 24, 2026
9c27cee
fix(web): render the user turn as markdown, like the assistant
Aug 24, 2026
a7f8930
feat(web): outline each conversation row with its work state
Aug 24, 2026
ab44692
feat(web): replace the work queue with the conversations column
Aug 24, 2026
b60b07c
chore: rebalance git hooks and add a CI secret scan
Aug 25, 2026
8003245
feat(contract): add repository attachments to a task record
Aug 25, 2026
8882c3c
feat(cli): conversations that run without a repository
Aug 25, 2026
63e9175
feat(web): show a conversation with no repository
Aug 25, 2026
a908fb5
docs: changelog and version for 0.14.0
Aug 25, 2026
a4f5fb8
Merge branch 'feat/forge-board-ui' into develop
Aug 25, 2026
538efa5
Merge branch 'feat/conversation-without-repo' into develop
Aug 25, 2026
82ace22
feat(web): compose a conversation with no repository
Aug 25, 2026
3944e99
fix(web): start every new conversation without a repository
Aug 25, 2026
af225a4
refactor(web): drop pinning and add the navigation rail keys
Aug 25, 2026
055d194
feat(cli): serve git worktrees over the api
Aug 25, 2026
d6f8f2d
feat(web): add the pure workspace navigation model
Aug 25, 2026
a1ed1ee
refactor(web): reduce the focus deck to a single view
Aug 25, 2026
90a0dcd
feat(web): load the worktrees of the active project
Aug 25, 2026
9a4ecc0
feat(web): build the repository branch rows and tiles
Aug 25, 2026
d9365f4
refactor(web): let the draft mode decide the no-repository panel
Aug 25, 2026
834e1d5
feat(web): add the navigation rail and its two list columns
Aug 25, 2026
8c3bb8a
feat(web): filter and sort the repository branch rows
Aug 25, 2026
ef944c5
refactor(web): move the search out of the header into the list column
Aug 25, 2026
828f9d8
feat(web): add the tabbed repository view
Aug 25, 2026
17902c6
feat(web): assemble the three-zone workspace navigation
Aug 25, 2026
7a4fe82
docs: record the workspace navigation rewrite
Aug 25, 2026
d3ab2ad
fix(web): give the branch sort options their own labels
Aug 25, 2026
605d9f8
docs: say precisely what the compose-target bug cost
Aug 25, 2026
8101ba4
Merge branch 'feat/workspace-nav-rewrite' into develop
Aug 25, 2026
631c0f0
refactor(web): rename the review focus mode component
Aug 25, 2026
931ef98
feat(web): model review targets and runs in the focus view
Aug 25, 2026
5efa13e
refactor(web): extract the review session out of App.vue
Aug 25, 2026
e7b8a58
refactor(web): trim the legacy review ui to reading only
Aug 25, 2026
a9cdc13
feat(web): build the code review rows across every project
Aug 25, 2026
b6f05e8
fix(cli): scope the mr review runner to the requested project
Aug 25, 2026
57b2b8d
feat(web): add the code review rail category and its panels
Aug 25, 2026
3894a97
feat(web): wire the code review category into the workspace
Aug 25, 2026
1fcd6c9
chore(web): drop the message keys the legacy sidebars owned
Aug 25, 2026
4ab5d49
docs: record the code review workspace category
Aug 25, 2026
db2114f
feat: add the brain arm mode
Aug 26, 2026
3b67cf7
fix(web): satisfy the repo-wide lint gate
Aug 26, 2026
5e3f017
fix(cli): give brain test repos an inline git identity
Aug 26, 2026
a8643bf
test: cover export, fix prompt and review stream handlers
Aug 26, 2026
8887edc
Merge pull request #92 from getCodesema/feat/brain-arm-mode
naashw Aug 26, 2026
7215015
feat(contract): add proof methods, finding repros and arm orders
Aug 26, 2026
703c5e9
feat(cli): wire mechanical evidence into the review gate
Aug 26, 2026
2b4dd6c
feat(cli): make ship and merge crash-safe with post-merge replay
Aug 26, 2026
3ca6fed
feat(cli): real brain daemon with local status and remote orders
Aug 26, 2026
8c01f46
docs: record the judgment hardening in the changelog
Aug 26, 2026
89ac3ab
chore: date the 0.15.0 changelog entry
Aug 26, 2026
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
42 changes: 41 additions & 1 deletion .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,30 @@ permissions:
contents: read

jobs:
# The pre-commit and pre-push hooks already scan for secrets, but only on the
# machines where `bun run prepare` succeeded, and `--no-verify` is one flag
# away. This is the copy that cannot be skipped. It is its own job so it does
# not queue behind `bun install`, and it needs the full history: a secret is
# in the branch whether it arrived in the last commit or the first.
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

# The binary rather than gitleaks-action: the action wants a licence key
# for organisation-owned repositories, and pinning the version keeps CI
# and the hooks finding the same things.
- name: Install gitleaks
env:
GITLEAKS_VERSION: 8.30.1
run: |
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
| sudo tar -xz -C /usr/local/bin gitleaks

- run: gitleaks git --no-banner --redact .

quality:
runs-on: ubuntu-latest
steps:
Expand All @@ -27,13 +51,29 @@ jobs:

- run: bun run lint

- run: bun run knip

# Known advisories against the installed tree. Every package this can
# flag today is a BUILD-time dependency: `codesema` ships with no runtime
# dependencies at all, so nothing here reaches a user's machine by being
# installed. It still matters, because these packages execute during
# `bun run build` and that build produces the `dist` we publish.
#
# Two transitive packages are pinned past their advisories through the
# `overrides` block in the root package.json (postcss, and the nanoid it
# pulls). Their parents — vite, vue, @vue/compiler-sfc — still declare
# ranges that resolve to the vulnerable versions, so removing the override
# silently reintroduces both. Drop an entry only once its parent has moved
# on, and confirm with `bun run audit` rather than by reading the range.
- run: bun run audit

- run: bun run format:check

- run: bun run typecheck

- run: bun run build

- run: bun run test
- run: bun run test:coverage

- run: bunx publint packages/cli

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ dist/
web-dist/
.codesema/
*.log

# only produced when the coverage run is asked for a file reporter (lcov);
# the default text reporter of scripts/coverage-gate.mjs writes nothing to disk
coverage/
.DS_Store
.env
.env.*
Expand Down
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ web-dist
coverage
bun.lock
CHANGELOG.md

# Committed copies of the brain repo's own generated JSON Schemas
# (packages/contract/scripts/sync-brain-schemas.mjs). Left in the brain's own
# export format so a sync is a plain copy, never a copy plus a reformat.
packages/contract/fixtures/cerveau-schemas
103 changes: 103 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

66 changes: 57 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@ refuses to start without the embedded web UI that `build` produces.

## The scripts

Costs measured on 16 cores, caches warm; they are there to tell the cheap
checks from the expensive ones, not to be hit exactly.

| Script | What it does | Cost |
| -------------- | ------------------------------------------------ | ----- |
| `lint` | oxlint over the workspace | ~0.2s |
| `format:check` | prettier, with its cache | ~0.8s |
| `typecheck` | builds the contract, then tsc ×2 + vue-tsc | ~5.8s |
| `lint` | oxlint over the workspace | ~0.3s |
| `audit` | known advisories against the installed tree | ~0.3s |
| `knip` | unused files, exports and dependencies | ~2.7s |
| `format:check` | prettier, with its cache | ~5s |
| `typecheck` | builds the contract, then tsc ×2 + vue-tsc | ~9.4s |
| `build` | contract, then web, then cli | ~2.8s |
| `test` | builds the contract, then the suite | ~10s |
| `verify` | typecheck + test, building the contract **once** | ~15s |
| `test` | builds the contract, then the suite in parallel | ~23s |
| `verify` | typecheck + test, building the contract **once** | ~31s |

`typecheck:only` and `test:only` skip the contract build, for when you know it
is already current. `typecheck` and `test` keep it, so both stay usable on
Expand All @@ -32,7 +37,7 @@ cached (`node_modules/.cache/prettier/`). Both caches live under
worktree pays full price, every run after is fast.

The suite runs in parallel **locally only**, on half the cores, computed at run
time — about 8s instead of 30s. One worker per core sounds better and is not:
time — 21s instead of 66s. One worker per core sounds better and is not:
each worker spawns real `git` subprocesses, so the real load runs well past the
core count, and tests start failing on their timeout rather than on their
assertions.
Expand All @@ -44,18 +49,61 @@ request and then hung for twenty on the merge queue's branch. Locally a person
is watching and can interrupt; on CI nobody is, and a job that hangs costs far
more than the twenty seconds it saved.

## Working on the web UI

`packages/cli/web-dist` is a build: editing `packages/web` and re-running
`bun run build` between every change is the slow way. For hot module
replacement, run the two halves side by side.

```sh
bun run dev:web # terminal 1: Vite on 5173
bun run dev:cli workspace # terminal 2: the CLI, pointed at it
```

Open the URL the **CLI** prints, not Vite's. This is Vite's backend
integration mode (https://vite.dev/guide/backend-integration): the CLI keeps
serving the page, so `/api`, the SSE streams and the tokens it injects into the
page all stay exactly as they are in a real install, while Vite serves the
modules and drives HMR. There is no proxy and no second origin to reason about.

`dev:cli` is only a shorthand for `CODESEMA_DEV_VITE=http://localhost:5173`.
Nothing reads that variable unless you set it, so a published install can never
fall into this mode; the value must be a loopback origin, since it ends up as a
`<script src>` on the page. `packages/web/vite.config.ts` pins port 5173 with
`strictPort`, so a busy port fails loudly instead of drifting to 5174 while the
CLI keeps pointing at 5173.

The dev shell lives in `devIndexHtml` (`packages/cli/src/serve.ts`) and mirrors
`packages/web/index.html`; a test fails if the two drift apart.

## Hooks

Lefthook runs them; `bun run prepare` installs it.

- **pre-commit** — gitleaks on the staged diff, prettier on the staged files
(restaged after), oxlint on the staged `.ts`/`.mjs`/`.vue`
- **pre-push** — `typecheck`, then `test`
- **pre-commit** (~4s) — gitleaks on the staged diff, prettier on the staged
files (restaged after), oxlint on the staged `.ts`/`.mjs`/`.vue`
- **commit-msg** (~1s): commitlint, cf. `commitlint.config.mjs`
- **pre-push** (~40s): the contract build, then gitleaks, `typecheck:only`,
`knip` and the full suite, all four at once

What sits in which hook follows one rule: a check belongs to the earliest hook
it can pay for itself in. Anything under a second and scoped to what you staged
goes in pre-commit; anything that needs the whole workspace, or costs seconds,
waits for the push; anything that needs the network, the whole history or a
published artefact stays in CI. That is why `audit`, `format:check` over the
repo, `publint` and the coverage gate are not in a hook, and why the pre-push
jobs run as a group: the hook costs what its slowest job costs, so the secret
scan and `knip` disappear behind the test run.

The pre-push hook is the local gate. There is no need to run the battery by
hand before pushing; the hook runs it and refuses the push if it fails. Never
reach for `--no-verify` to get around it.

The one check that also exists server-side is the secret scan: the `secrets` job
in the `quality` workflow rescans the full history on every pull request, so a
push that skipped the hooks (or came from a machine where `bun run prepare`
failed) still gets caught.

## Branches and merging

`develop` is the integration branch. `main` only ever receives `develop`.
Expand Down
Loading
Loading