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
36 changes: 29 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
# shotkit

A Playwright capture engine for store/social assets, used via the `shotkit` CLI,
`capture()` programmatically, or (planned) an MCP tool. Vanilla JS, CommonJS, no
build step.
`capture()` programmatically, or the `skills/capture/` Claude Code skill.
Vanilla JS, CommonJS, no build step.

## Run this tool (for agents)

To capture store/social assets from a repo that has a `shotkit.config.js`
(or legacy `store.config.js`):

```bash
npx @starter-series/shotkit --json # all assets; stdout = {ok, outDir, produced[]}
npx @starter-series/shotkit <path> --json # run against another checkout
```

Prereqs: `npx playwright install chromium` (one-time); the config's `build`
command must succeed. Loading an MV3 extension needs a **headed** Chromium —
works as-is locally, `xvfb-run` in CI. Exit codes: `0` ok · `1` runtime
failure · `2` usage / no config. In `--json` mode progress logs go to stderr;
stdout is exactly one JSON object. Useful flags: `--scene <name>`,
`--no-video`, `--no-build`.

## Structure

Expand All @@ -16,8 +33,10 @@ src/
promo.js → renderPromoTile (HTML template → image)
describe.js → extractListing / renderDescriptionDoc (STORE_LISTING.md → copy)
presets.js → PRESETS / resolveSize (CWS + SNS sizes)
cli.js → CLI arg parsing + config resolution (unit-tested)
index.js → public API (the contract — don't break exports)
bin/shotkit.js → CLI (thin wrapper over capture())
bin/shotkit.js → CLI (thin wrapper over capture(); --json agent contract)
skills/capture/ → Claude Code skill wrapping the CLI (Agent Skills format)
test/ → unit tests for the pure/safe modules (no browser)
```

Expand All @@ -41,11 +60,14 @@ test/ → unit tests for the pure/safe modules (no browser)
## Generalization rule (for the next starter-series capability)

One npm package (engine + thin CLI), one `*.config.js` seam for irreducible
per-repo intent, one MCP tool taking a `path`, one Claude Code skill, one
marketplace entry. **The engine never reads project specifics except through the
config seam.** shotkit is the reference implementation of this pattern; mirror
per-repo intent, **agent surfaces matched to the tool's nature** — fast /
structured-data tools get an MCP tool taking a `path` (like `create-starter`'s
audits); heavy, file-producing build tools like shotkit get a `--json` CLI +
Claude Code skill + AGENTS.md run-block instead — plus one marketplace entry.
**The engine never reads project specifics except through the config seam.**
shotkit is the reference implementation of the non-MCP branch; mirror
[`create-starter`](https://github.com/starter-series/create-starter) for the
CLI+MCP+plugin surfaces when adding them.
MCP branch.

## Dev

Expand Down
35 changes: 24 additions & 11 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

## 상태와 범위 (Status & Scope)

- **현재 구현된 것** — Playwright 캡처 **엔진**(빌드 → `--load-extension`으로 *빌드된* 익스텐션 로드 → scene 구동 → 스크린샷 → 캡션/면책 밴드 → HTML 프로모 타일 → 데모 `webm` → `STORE_LISTING.md`에서 문안 추출), **CLI**(`shotkit`), 양쪽 용도 **사이즈 프리셋**(CWS `1280×800`/`440×280`, SNS `1200×675`/`1200×630`/`1080×1080`), **path-traversal 안전** 로컬 픽스처 서버, 프로그램 API(`capture()`). `browser-extension-starter`·`skillBridge`가 소비.
- **계획된 것** — **MCP stdio 도구**(`capture_assets({ path })`) — 에이전트가 어느 체크아웃이든 repo당 설치 없이 캡처 실행; **Claude Code skill/command**(`/capture`); `starter-series` 플러그인 **마켓플레이스** 등재; **동영상 편집**(`webm → mp4`, 트림, 캡션); OIDC npm publish.
- **설계 의도** — *엔진 1개, 표면 여러 개* ([`create-starter`](https://github.com/starter-series/create-starter)가 이미 증명한 패턴: CLI + MCP + skill). 캡처는 **결정적**(로그인 불필요 픽스처, freeze된 데이터)이고, 실행이 **실제 빌드본 smoke test를 겸함** — 스크린샷이 나온다 = 그 기능이 출하 코드에서 렌더됨. 모든 샷에 면책 밴드를 합성해 **상표 안전**.
- **하지 않기로 한 것** — repo별 **scene 설정** 제거(어떤 화면이 *당신의* money shot인지는 환원 불가한 의도 — `shotkit.config.js`에 둠). 범용 동영상 편집기(v1은 깔끔한 녹화만; 편집은 계획). 호스티드 서비스(파일을 만지는 캡처는 본질적으로 로컬/stdio).
- **현재 구현된 것** — Playwright 캡처 **엔진**(빌드 → `--load-extension`으로 *빌드된* 익스텐션 로드 → scene 구동 → 스크린샷 → 캡션/면책 밴드 → HTML 프로모 타일 → 데모 `webm` → `STORE_LISTING.md`에서 문안 추출), **에이전트 계약**을 갖춘 **CLI**(`shotkit` — `--json` 머신 출력, 선택적 `path` 인자, `0/1/2` 종료 코드), 양쪽 용도 **사이즈 프리셋**(CWS `1280×800`/`440×280`, SNS `1200×675`/`1200×630`/`1080×1080`), **path-traversal 안전** 로컬 픽스처 서버, 프로그램 API(`capture()`), **Claude Code skill**([`skills/capture/`](skills/capture/SKILL.md)), 그리고 셸을 가진 어떤 코딩 에이전트든 호출법을 읽을 수 있는 **AGENTS.md 실행 블록**. `browser-extension-starter`·`skillBridge`가 소비.
- **계획된 것** — npm publish(그 전까지는 `github:starter-series/shotkit#v1.1.0`로 설치); **capture-in-CI GitHub Action**(공식 Playwright 이미지 + `xvfb`로 캡처를 CI에서 돌리고 `store-assets/`를 artifact로 업로드 — 로컬 브라우저 0); `starter-series` 플러그인 **마켓플레이스** 등재; **동영상 편집**(`webm → mp4`, 트림, 캡션).
- **설계 의도** — *엔진 1개, 표면 여러 개 — 단, 도구 성격에 맞는 표면.* shotkit은 무겁고 파일을 산출하는 빌드 도구라 표면이 CLI(+`--json`)·skill·CI입니다 — MCP가 아니라(하지 않기로 한 것 참고). 캡처는 **결정적**(로그인 불필요 픽스처, freeze된 데이터)이고, 실행이 **실제 빌드본 smoke test를 겸함** — 스크린샷이 나온다 = 그 기능이 출하 코드에서 렌더됨. 모든 샷에 면책 밴드를 합성해 **상표 안전**.
- **하지 않기로 한 것** — **MCP 서버**(의도적으로 폐기: 셸이 있는 에이전트에는 `--json` + skill이 세션당 컨텍스트 비용 없이 더 나은 계약이며, 여기엔 빠른 구조화 질의가 없음). repo별 **scene 설정** 제거(어떤 화면이 *당신의* money shot인지는 환원 불가한 의도 — `shotkit.config.js`에 둠). 범용 동영상 편집기(v1은 깔끔한 녹화만; 편집은 계획). 호스티드 서비스(파일을 만지는 캡처는 본질적으로 로컬).
- **공개하지 않음** — 없음.

## 설치
Expand All @@ -32,7 +32,10 @@ npm i -D @starter-series/shotkit
npx playwright install chromium # 최초 1회: shotkit이 구동할 브라우저
```

설정 파일이 있는 repo면 무설치 실행:
> npm publish는 준비 중입니다 — 그 전까지는 GitHub에서 설치하십시오:
> `npm i -D github:starter-series/shotkit#v1.1.0`

게시 후에는 설정 파일이 있는 repo면 무설치 실행이 가능합니다:

```bash
npx @starter-series/shotkit
Expand All @@ -45,19 +48,29 @@ npx @starter-series/shotkit
`shotkit.config.js`(repo별 이음새 — 영문 README의 contract 참고)를 두고:

```bash
shotkit # outDir에 전부 산출
shotkit --scene 01-feature # 특정 scene/타일/데모 또는 "description"만
shotkit --no-video # 스크린캐스트 생략
shotkit --no-build # 이미 빌드된 번들 사용
shotkit # outDir에 전부 산출
shotkit --scene 01-feature # 특정 scene/타일/데모 또는 "description"만
shotkit --no-video # 스크린캐스트 생략
shotkit --no-build # 이미 빌드된 번들 사용
shotkit ../my-extension --json # 다른 체크아웃 대상 실행; 결과 JSON을 stdout에
```

산출물은 `outDir`(기본 `store-assets/`): `<scene>.png`, `<promoTile>.png`, `<demo>.webm`, `description.md`.

### 에이전트 계약 (`--json`)

`shotkit [path] --json`은 stdout에 **정확히 하나의 JSON 객체**를 출력합니다
(진행 로그는 stderr로 이동): `{ "ok": true, "outDir": …, "produced": [절대경로…] }`.
종료 코드: `0` 정상 · `1` 런타임 실패(stderr에 `{"ok":false,"error":…}`) ·
`2` 사용법 오류/설정 없음. 에이전트 연결은 [`AGENTS.md`](AGENTS.md) 실행 블록
(Claude Code·Codex·Cursor·Gemini CLI 등이 읽음)과 [`skills/capture/`](skills/capture/SKILL.md)
skill(Agent Skills 표준 — 호환 도구의 skills 디렉터리에 폴더째 복사)을 참고하십시오.

## 로드맵 — 엔진 1개, 표면 여러 개

CLI(✅) · `capture()`(✅) · **MCP stdio 도구**(계획, 에이전트용) · Claude Code skill(계획) · 마켓플레이스 등재(계획) · 동영상 편집(계획).
CLI `--json`+`path`(✅) · `capture()`(✅) · Claude Code skill(✅) · AGENTS.md 실행 블록(✅) · npm publish(계획) · capture-in-CI GitHub Action(계획) · 마켓플레이스 등재(계획) · 동영상 편집(계획). MCP stdio 도구는 검토 후 **폐기** — "하지 않기로 한 것" 참고.

**일반화 규칙**(시리즈의 다음 기능용): npm 패키지 1개(엔진+얇은 CLI) + `*.config.js` 이음새 1개 + `path` 받는 MCP 도구 1개 + Claude Code skill 1개 + 마켓플레이스 항목 1개. **엔진은 config 이음새 외엔 프로젝트 특이사항을 읽지 않는다.**
**일반화 규칙**(시리즈의 다음 기능용): npm 패키지 1개(엔진+얇은 CLI) + `*.config.js` 이음새 1개 + **도구 성격에 맞는 에이전트 표면**(빠른 구조화 도구: `path` 받는 MCP 도구 / 무거운 빌드 도구: `--json` CLI + skill + AGENTS.md 블록) + 마켓플레이스 항목 1개. **엔진은 config 이음새 외엔 프로젝트 특이사항을 읽지 않는다.**

## 라이선스

Expand Down
49 changes: 36 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ Screenshots · promo images · demo screencast · listing copy. One command.

## Status & Scope

- **Currently implemented** — A Playwright capture **engine** (build → launch the *built* extension via `launchPersistentContext(--load-extension)` → drive scenes → screenshot → caption/disclaimer band → promo tile from HTML → demo `webm` → listing copy from `STORE_LISTING.md`), a **CLI** (`shotkit`), **size presets** for both audiences (CWS `1280×800`/`440×280`, SNS `1200×675`/`1200×630`/`1080×1080`), a **path-traversal-safe** localhost fixture server, and a programmatic API (`capture()`). Consumed by `browser-extension-starter` and `skillBridge`.
- **Planned** — an **MCP stdio tool** (`capture_assets({ path })`) so an agent can run captures against any checkout with zero per-repo install; a **Claude Code skill/command** (`/capture`); a listing in the `starter-series` plugin **marketplace**; **video editing** (`webm → mp4`, trim, captions) for SNS; npm publish via OIDC.
- **Design intent** — *One engine, many surfaces* (the pattern [`create-starter`](https://github.com/starter-series/create-starter) already proves: a single engine fronted by CLI + MCP + skill). Captures are **deterministic** (login-free fixtures, frozen data) and the run **doubles as a real-bundle smoke test** — a screenshot only appears if that feature rendered from the shipped code. **Trademark-safe** by construction: a disclaimer band is composited onto every shot.
- **Non-goals** — Removing the per-repo **scene config** (which screens are *your* money shots is irreducible intent — it lives in your `shotkit.config.js`). A general-purpose video editor (v1 records a clean screencast; editing is Planned). A hosted service (file-touching capture is local/stdio by nature).
- **Currently implemented** — A Playwright capture **engine** (build → launch the *built* extension via `launchPersistentContext(--load-extension)` → drive scenes → screenshot → caption/disclaimer band → promo tile from HTML → demo `webm` → listing copy from `STORE_LISTING.md`), a **CLI** (`shotkit`) with an **agent contract** (`--json` machine output, optional `path` argument, `0/1/2` exit codes), **size presets** for both audiences (CWS `1280×800`/`440×280`, SNS `1200×675`/`1200×630`/`1080×1080`), a **path-traversal-safe** localhost fixture server, a programmatic API (`capture()`), a **Claude Code skill** ([`skills/capture/`](skills/capture/SKILL.md)), and an **AGENTS.md run-block** so any shell-having coding agent can invoke it. Consumed by `browser-extension-starter` and `skillBridge`.
- **Planned** — npm publish (until then install via `github:starter-series/shotkit#v1.1.0`); a **capture-in-CI GitHub Action** (run the capture under `xvfb` on the official Playwright image and upload `store-assets/` as an artifact — zero local browser); a listing in the `starter-series` plugin **marketplace**; **video editing** (`webm → mp4`, trim, captions) for SNS.
- **Design intent** — *One engine, many surfaces — matched to the tool's nature.* shotkit is a heavy, file-producing build tool, so its surfaces are CLI (+`--json`), skill, and CI — not MCP (see Non-goals). Captures are **deterministic** (login-free fixtures, frozen data) and the run **doubles as a real-bundle smoke test** — a screenshot only appears if that feature rendered from the shipped code. **Trademark-safe** by construction: a disclaimer band is composited onto every shot.
- **Non-goals** — An **MCP server** (dropped by design: agents with a shell get a better contract from `--json` + the skill, without MCP's per-session context cost; nothing here is a fast structured query). Removing the per-repo **scene config** (which screens are *your* money shots is irreducible intent — it lives in your `shotkit.config.js`). A general-purpose video editor (v1 records a clean screencast; editing is Planned). A hosted service (file-touching capture is local by nature).
- **Redacted** — none. Ships no private data, credentials, or third-party identifiers.

## Install
Expand All @@ -34,7 +34,10 @@ npm i -D @starter-series/shotkit
npx playwright install chromium # one-time: the browser shotkit drives
```

Or zero-install in any repo that has a config:
> npm publish is pending — until it lands, install from GitHub:
> `npm i -D github:starter-series/shotkit#v1.1.0`

Once published, zero-install works in any repo that has a config:

```bash
npx @starter-series/shotkit
Expand All @@ -47,14 +50,30 @@ npx @starter-series/shotkit
Add a `shotkit.config.js` (the per-repo seam — see the contract below), then:

```bash
shotkit # produce everything into outDir
shotkit --scene 01-feature # just one scene/promoTile/demo, or "description"
shotkit --no-video # skip the screencast (faster/CI)
shotkit --no-build # use an already-built bundle
shotkit # produce everything into outDir
shotkit --scene 01-feature # just one scene/promoTile/demo, or "description"
shotkit --no-video # skip the screencast (faster/CI)
shotkit --no-build # use an already-built bundle
shotkit ../my-extension --json # run against another checkout; JSON result on stdout
```

Outputs land in `outDir` (default `store-assets/`): `<scene>.png`, `<promoTile>.png`, `<demo>.webm`, `description.md`.

### Agent contract (`--json`)

`shotkit [path] --json` prints **exactly one JSON object** to stdout (progress
logs move to stderr):

```json
{ "ok": true, "outDir": "/abs/store-assets", "produced": ["/abs/store-assets/01-popup.png"] }
```

Exit codes: `0` ok · `1` runtime failure (stderr carries `{"ok":false,"error":…}`) ·
`2` usage / no config found. Drop-in agent wiring: the run-block in
[`AGENTS.md`](AGENTS.md) (read by Claude Code, Codex, Cursor, Gemini CLI, …) and
the [`skills/capture/`](skills/capture/SKILL.md) skill (Agent Skills format —
copy the folder into any compatible tool's skills directory).

## Config contract (`shotkit.config.js`)

```js
Expand Down Expand Up @@ -99,14 +118,18 @@ module.exports = {

| Surface | Status | For |
|---|---|---|
| CLI (`shotkit`, `npx`) | ✅ now | humans / CI, zero-install |
| CLI (`shotkit`, `npx`) with `--json` + `path` | ✅ now | humans / CI / **shell-having agents** |
| Programmatic `capture()` | ✅ now | embedding |
| **MCP stdio tool** `capture_assets({ path })` | planned | **agents, any repo, no install** |
| Claude Code skill/command `/capture` | planned | Claude Code users |
| Claude Code skill ([`skills/capture/`](skills/capture/SKILL.md)) | ✅ now | Claude Code (portable to Codex/Cursor/Gemini via the Agent Skills format) |
| `AGENTS.md` run-block | ✅ now | every agent that reads AGENTS.md |
| npm publish | planned | `npx` zero-install |
| Capture-in-CI GitHub Action (xvfb + artifact) | planned | zero-local-browser first run + CI smoke test |
| `starter-series` marketplace entry | planned | discovery |
| Video editing (`webm→mp4`, trim, captions) | planned | SNS clips |

**Generalization rule** (for the next capability in the series): *one npm package (engine + thin CLI), one `*.config.js` seam for irreducible per-repo intent, one MCP tool taking a `path`, one Claude Code skill, one marketplace entry. The engine never reads project specifics except through the config seam.*
An MCP stdio tool was considered and **dropped** — see Non-goals: shotkit is a heavy, file-producing build tool, so a `--json` CLI + skill serves agents better than an MCP server's per-session context cost.

**Generalization rule** (for the next capability in the series): *one npm package (engine + thin CLI), one `*.config.js` seam for irreducible per-repo intent, agent surfaces matched to the tool's nature (fast/structured: an MCP tool taking a `path`; heavy/build-time: a `--json` CLI + skill + AGENTS.md run-block), one marketplace entry. The engine never reads project specifics except through the config seam.*

## License

Expand Down
Loading