Skip to content

Commit 69956c8

Browse files
committed
feat: add review lanes and polish blog assets
1 parent ad7f408 commit 69956c8

19 files changed

Lines changed: 1229 additions & 67 deletions

QUICK_REFERENCE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,23 @@ All endpoints are served by `git cms serve` (default port 4638). Slugs are NFKC-
113113
| `POST` | `/api/cms/unpublish` | `{ slug }` | Unpublish an article |
114114
| `POST` | `/api/cms/revert` | `{ slug }` | Revert to draft state |
115115
| `GET` | `/api/cms/history` | `?slug=xxx&limit=50` | List version history (max 200) |
116+
| `GET` | `/api/cms/reviews` | `?slug=xxx` | List review lanes for one article |
117+
| `GET` | `/api/cms/review` | `?slug=xxx&laneId=yyy` | Read one review lane's visible proposal state |
118+
| `POST` | `/api/cms/review/create` | `{ slug, owner (optional) }` | Create a speculative review lane pinned to the current article state |
119+
| `POST` | `/api/cms/review/snapshot` | `{ slug, laneId, title, body, trailers (optional) }` | Save speculative edits into a review lane without touching the live draft |
120+
| `POST` | `/api/cms/review/apply` | `{ slug, laneId }` | Apply a review lane by writing a new draft commit |
116121
| `GET` | `/api/cms/show-version` | `?slug=xxx&sha=<oid>` | Read a specific historical version |
117122
| `POST` | `/api/cms/restore` | `{ slug, sha }` | Restore a historical version as new draft |
118123
| `POST` | `/api/cms/upload` | `{ slug, filename, data }` | Upload base64-encoded asset (optionally encrypted server-side) |
119124

120125
Historical version endpoints currently assume Git's default SHA-1 object format and therefore validate 40-character hexadecimal commit IDs.
121126

127+
Review-lane note:
128+
129+
- review lanes use `git-warp` working sets for speculative editorial state
130+
- the live draft stays untouched until `POST /api/cms/review/apply`
131+
- apply writes a new draft commit; it does not replace history or mutate the working set into truth
132+
122133
---
123134

124135
## State Machine

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ A Git-native, database-free CMS: article bodies in commit messages, publish by m
66

77
> "I'm using `git push` as my API endpoint."
88
9-
`git-cms` treats Git as an application substrate, not just a version-control tool. Article bodies live in commit messages on empty-tree commits. Draft and published state live in refs. History falls out of the storage model instead of being layered on afterward.
9+
`git-cms` treats Git as an application substrate, not just a version-control tool. Article bodies live in commit messages on empty-tree commits. Draft and published state live in refs. History falls out of the storage model instead of being layered on afterward. Review lanes use `git-warp` working sets so speculative edits can stay off the live draft until they are explicitly applied back as a new commit.
1010

1111
Full article: [Git as CMS](https://flyingrobots.dev/git-stunts/git-cms)
1212

@@ -69,6 +69,7 @@ The stunt is narrow on purpose:
6969
- published state lives at `refs/_blog/dev/published/<slug>`
7070
- publishing is pointer movement
7171
- restore writes a new commit from old content
72+
- review lanes live in `git-warp` working sets and apply back as new draft commits
7273
- history is the storage model
7374

7475
The admin UI exists to prove the model is usable. It is not the point of the project.
@@ -120,6 +121,7 @@ git -C "$GIT_CMS_REPO" log refs/_blog/dev/articles/hello-world --graph --oneline
120121
- The commit points at the empty tree.
121122
- Publishing moves `refs/_blog/dev/published/<slug>` to the current draft tip.
122123
- Restoring an old version creates a new commit instead of rewriting history.
124+
- Review lanes hold speculative edits off to the side until `Apply Lane` writes them back as a fresh draft commit.
123125

124126
This is the core of the stunt. Before Git can pretend to be a CMS, it has to behave like storage and state first.
125127

@@ -146,6 +148,7 @@ If you are here because of the article, start with `demo` or `sandbox`, not `dev
146148
- **Fast-forward publish semantics:** Published refs only move to the current draft tip
147149
- **Atomic publishes:** Publish is a CAS-protected ref update
148150
- **Infinite history:** Every draft save is a commit
151+
- **Speculative review lanes:** Review lanes use `git-warp` working sets and only affect the live article when you explicitly apply them
149152
- **Optional asset encryption:** Assets can be encrypted server-side via `@git-stunts/git-cas`
150153

151154
## Contributor Workflow

docs/GIT_CMS_COMPANION.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ With `npm run sandbox` running:
6565

6666
The important thing is that restore does not rewrite history. It appends a new commit using older content.
6767

68+
## Review Lanes
69+
70+
`git-cms` now has one deliberately narrow editorial feature layered on top of the core draft/publish model: review lanes.
71+
72+
- the live draft stays where it is
73+
- a review lane stores speculative edits in a `git-warp` working set
74+
- `Apply Lane` writes those edits back as a new draft commit
75+
76+
That means a review lane is not a second truth. It is a pinned sidecar for proposed edits until you deliberately promote it.
77+
6878
## Key Code Paths
6979

7080
If you want to read the implementation alongside the article, start here:
@@ -73,6 +83,7 @@ If you want to read the implementation alongside the article, start here:
7383
- `saveSnapshot()` for draft creation
7484
- `publishArticle()` for ref movement
7585
- `getArticleHistory()` and `restoreVersion()` for version browsing and restore
86+
- `createReviewLane()`, `saveReviewLaneSnapshot()`, and `applyReviewLane()` for speculative editorial state
7687
- [src/server/index.js](../src/server/index.js)
7788
- thin HTTP layer over `CmsService`
7889
- [scripts/prepare-playground.sh](../scripts/prepare-playground.sh)
@@ -91,11 +102,13 @@ Good fit:
91102

92103
Not the point:
93104

94-
- rich editorial workflows
105+
- full editorial workflow platforms
95106
- search and plugin ecosystems
96107
- collaborative editing
97108
- mainstream CMS feature parity
98109

110+
The new review lanes are intentionally small. They prove that `git-warp` can hold speculative editorial state cleanly, but they do not turn `git-cms` into a general collaborative CMS.
111+
99112
## Related Series Entries
100113

101114
- [Welcome to Git Stunts](https://flyingrobots.dev/git-stunts/welcome-to-git-stunts)

docs/media/README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,38 +37,45 @@ Implementation:
3737

3838
## `git-cas` terminal capture
3939

40-
This repo also carries a VHS starter for the sibling `git-cas` project so the series can produce consistent terminal-native motion assets.
40+
This repo also carries VHS starters for the sibling `git-cas` project so the series can produce consistent terminal-native motion assets.
4141

4242
Run it from this repo root:
4343

4444
```bash
4545
npm run capture:git-cas:vhs
46+
npm run capture:git-cas:tui
4647
```
4748

4849
Defaults:
4950

5051
- expects the `git-cas` source repo at `$HOME/git/git-stunts/git-cas`
51-
- creates a temporary throwaway repo at `/tmp/git-cas-vhs-demo`
52+
- creates a synthetic media root at `/tmp/git-stunts-media`
53+
- symlinks the real source repo into `/tmp/git-stunts-media/git-cas`
54+
- creates a throwaway Git repo at `/tmp/git-stunts-media/repo`
5255
- renders a GIF into `docs/media/generated/git-cas/`
5356

5457
Override the source repo path if needed:
5558

5659
```bash
5760
GIT_CAS_REPO=/absolute/path/to/git-cas npm run capture:git-cas:vhs
61+
GIT_CAS_REPO=/absolute/path/to/git-cas npm run capture:git-cas:tui
5862
```
5963

6064
Output file:
6165

6266
- `docs/media/generated/git-cas/git-cas-inspect.gif`
67+
- `docs/media/generated/git-cas/git-cas-dashboard.gif`
6368

6469
Implementation:
6570

6671
- [vhs/git-cas-inspect.tape](../../vhs/git-cas-inspect.tape)
72+
- [vhs/git-cas-dashboard.tape](../../vhs/git-cas-dashboard.tape)
6773
- [scripts/render-git-cas-vhs.sh](../../scripts/render-git-cas-vhs.sh)
6874

6975
## Notes
7076

7177
- The `git-cms` capture is meant for article-quality browser footage, not test coverage.
7278
- The filmed restore flow uses a draft-only article because restoring a still-published article is intentionally blocked by the product.
73-
- The VHS tape focuses on the `git-cas` inspect flow because it is concise, deterministic, and terminal-native.
79+
- The `git-cas` inspect tape is concise and deterministic. The dashboard tape captures the actual vault TUI.
80+
- The `git-cas` capture scripts intentionally render from synthetic `/tmp/git-stunts-media/...` paths and set a neutral shell prompt so the media does not leak local checkout paths like `/Users/james/...`.
7481
- If you want MP4 transcoding or caption burn-ins later, add that as a second pass. The canonical raw outputs here are WebM for browser footage and GIF for VHS.

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"quickstart": "./scripts/quickstart.sh",
2121
"setup": "./scripts/setup.sh",
2222
"capture:cms": "node ./scripts/capture-cms-footage.mjs",
23-
"capture:git-cas:vhs": "./scripts/render-git-cas-vhs.sh",
23+
"capture:git-cas:vhs": "./scripts/render-git-cas-vhs.sh inspect",
24+
"capture:git-cas:tui": "./scripts/render-git-cas-vhs.sh dashboard",
2425
"check:deps": "node scripts/check-dependency-integrity.mjs",
2526
"check:docs": "./scripts/check-doc-drift.sh",
2627
"test": "./test/run-docker.sh",
@@ -41,7 +42,7 @@
4142
"@git-stunts/alfred": "^0.10.3",
4243
"@git-stunts/docker-guard": "^0.1.0",
4344
"@git-stunts/git-cas": "^5.3.2",
44-
"@git-stunts/git-warp": "^14.3.0",
45+
"@git-stunts/git-warp": "^14.8.0",
4546
"@git-stunts/plumbing": "^2.8.0",
4647
"@git-stunts/trailer-codec": "^2.1.1",
4748
"@git-stunts/vault": "^1.0.1"

0 commit comments

Comments
 (0)