Skip to content
Draft
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
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI

on:
push:
pull_request:

permissions:
contents: read

jobs:
backend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install dependencies
run: pip install -r requirements.txt

- name: Pytest
env:
PYTHONPATH: .
run: pytest -q

extension:
runs-on: ubuntu-latest
defaults:
run:
working-directory: extension
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
cache-dependency-path: extension/package-lock.json

- name: Install and compile
run: |
npm ci
npm run compile
98 changes: 98 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Release

on:
workflow_dispatch:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
cache-dependency-path: extension/package-lock.json

- name: Install, compile, package
working-directory: extension
run: |
npm ci
npm run compile
npx --yes @vscode/vsce package

- name: Upload VSIX artifact
uses: actions/upload-artifact@v4
with:
name: creer-vsix
path: extension/*.vsix
if-no-files-found: error

github-release:
needs: [build]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download VSIX artifact
uses: actions/download-artifact@v4
with:
name: creer-vsix
path: dist

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: dist/*.vsix
generate_release_notes: true
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

publish:
needs: [build]
runs-on: ubuntu-latest
steps:
- name: Download VSIX artifact
uses: actions/download-artifact@v4
with:
name: creer-vsix
path: dist

- name: Publish (Marketplace / Open VSX when tokens present)
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
run: |
set -euo pipefail
cd dist
shopt -s nullglob
vsix=(*.vsix)
if [ ${#vsix[@]} -eq 0 ]; then
echo "No .vsix artifact found"
exit 1
fi
echo "Packaged: ${vsix[*]}"

published=false
if [ -n "${VSCE_PAT:-}" ]; then
echo "Publishing to VS Marketplace…"
npx --yes @vscode/vsce publish --packagePath "${vsix[0]}" -p "$VSCE_PAT"
published=true
fi
if [ -n "${OVSX_PAT:-}" ]; then
echo "Publishing to Open VSX…"
npx --yes ovsx publish "${vsix[0]}" -p "$OVSX_PAT"
published=true
fi
if [ "$published" = false ]; then
echo "No publish tokens configured — artifact only"
fi
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.DS_Store
*.log
.env
**/venv/
**/__pycache__/
**/node_modules/
**/out/
*.pyc
.pytest_cache/
28 changes: 28 additions & 0 deletions PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Creer — Final Plan

## Done

- **v0.1** — FastAPI planner/generator + VS Code write-to-workspace (+ optional git)
- **v0.2** — Preview, GitHub create/push, templates, overwrite protection, `/creer` chat
- **v0.3** — Streaming, offline/local models, bake-ins, SecretStorage + GIT_ASKPASS
- **v0.4** — Stream cancel, selectable license/CI bake-ins, quality gates
- **v0.5** — Content diff preview before write, multi-root workspace targeting, installable JSON/YAML template packs
- **v0.6** — Pack marketplace + remote URL install/delete, side-by-side conflict diffs, publish packaging
- **v0.7** — Self-hosted pack registry (`/registry` + download), extension icon, Browse Pack Registry, release changelog
- **v0.8** — Federated registry (`/registry/federated` + peers), Browse Federated Registry UI, GitHub Actions release + CI (artifact-first; signed publish when secrets exist)
- **v0.9** — Peer status/probe UX (`creer.registryPeers`, Manage Registry Peers), federated browse enrichment, GitHub Release on tag + `RELEASE.md`
- **v1.0** — Stable foundation: optional registry write auth (Bearer / `X-Creer-Token`), `GET /registry/discover`, federated `discover=true`, SecretStorage registry token + Discover peers UX
- **v1.1** — Discovery hardening: peer policy (SSRF / private IP blocks, allow/deny, max hops); extension surfaces policy errors, `creer.federationMaxHops` / `creer.warnPrivatePeers`, blocked-discover UX

## Optional next

- Human: configure `VSCE_PAT` / `OVSX_PAT` repository secrets; tag `v1.1.0` (see [`RELEASE.md`](RELEASE.md)) — agents cannot set GitHub Actions secrets
- Signed peer trust / mutual TLS between registries

## Non-goals

- Multi-agent orchestration
- Memory graphs
- Overengineered plugin frameworks

Stay power-focused: idea → plan → files → workspace.
106 changes: 106 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Creer

AI-powered repo scaffolding inside your workspace.

**Current version: 1.1.0** (discovery hardening)

## Architecture

```
creer/
├── backend/ # Python FastAPI AI engine (+ packs/ + registry)
├── extension/ # VS Code extension (icon in media/)
└── .github/ # CI + release workflows
```

## Quick start

```bash
# Backend
cd backend && python -m venv venv && source venv/bin/activate
pip install -r requirements.txt && cp .env.example .env
uvicorn main:app --reload --port 8000

# Extension
cd extension && npm install && npm run compile
# F5 → Creer: Create New Repo
```

## Registry & federation (v0.7–v1.1)

Self-hosted pack catalog plus optional multi-host federation, write auth, and peer policy:

| Method | Path | Description |
|---|---|---|
| `GET` | `/registry?q=&source=` | Searchable pack list |
| `GET` | `/registry/federated?q=&source=&peers=&discover=&max_hops=` | Local + peer merge; `discover=true` expands peers; `max_hops` caps hop depth (0–2) |
| `GET` | `/registry/discover` | Peer discovery (policy-filtered in v1.1+) |
| `GET` | `/registry/peers` | Peer health + configured URLs |
| `POST` | `/registry/peers/probe` | Probe one peer `{ url }` (auth when configured; may 400 on policy) |
| `GET` | `/registry/packs/{id}` | Pack metadata |
| `GET` | `/registry/packs/{id}/download` | Portable JSON pack (installable URL) |
| `GET` | `/marketplace` | Curated featured view |
| `POST` | `/packs/install` | Install pack from URL (auth when configured) |
| `DELETE` | `/packs/{id}` | Delete installed pack (auth when configured) |

When the backend sets `CREER_REGISTRY_TOKEN`, mutating routes expect `Authorization: Bearer <token>` and/or `X-Creer-Token`.

### Peer policy env vars (v1.1)

Backend peer/federation policy (SSRF and private-IP hardening). The extension surfaces 400 `detail` strings and per-peer `error` / optional `policy` fields.

| Env | Purpose |
|---|---|
| `CREER_FEDERATION_MAX_HOPS` | Default max discovery hops (0–2; default 1). Extension may also send `max_hops` on federated browse when the backend accepts it. |
| `CREER_PEER_ALLOWLIST` | Comma-separated hostnames/URLs; if non-empty, only these peers may be contacted |
| `CREER_PEER_DENYLIST` | Comma-separated hostnames/URLs always blocked |
| `CREER_ALLOW_PRIVATE_PEERS` | When true (`1`/`true`/`yes`), allow loopback/private/link-local peers (default off) |

Extension settings: `creer.registryPeers`, `creer.showPeerStatus`, `creer.federatedDiscover` (`discover=true`), `creer.federationMaxHops` (`max_hops`), `creer.warnPrivatePeers`, `creer.registryToken` (deprecated plaintext — prefer SecretStorage).

Commands: **Browse Federated Registry**, **Manage Registry Peers** (Discover peers; private-host warning; policy-blocked suggestions), **Set / Clear Registry Token**.

Install from another Creer host:

```bash
curl -X POST http://localhost:8000/packs/install \
-H 'Content-Type: application/json' \
-d '{"url":"http://other-host:8000/registry/packs/fastapi-crud/download"}'
```

Set `CREER_PUBLIC_BASE_URL` for absolute download links in registry responses.
Set `CREER_REGISTRY_PEERS` for backend-configured federated discovery.
Set `CREER_REGISTRY_TOKEN` to require write auth on install/delete/probe.
Use `creer.registryPeers` in the extension for client-side extra peers when browsing.

## Extension commands

| Command | Title |
|---|---|
| `creer.createRepo` | Create New Repo |
| `creer.createRepoFromChat` | Create from Chat Prompt |
| `creer.browseMarketplace` | Browse Pack Marketplace |
| `creer.browseRegistry` | Browse Pack Registry |
| `creer.browseFederatedRegistry` | Browse Federated Registry |
| `creer.manageRegistryPeers` | Manage Registry Peers |
| `creer.installPackFromUrl` | Install Pack from URL |
| `creer.setGitHubToken` / `clearGitHubToken` | GitHub SecretStorage token |
| `creer.setRegistryToken` / `clearRegistryToken` | Registry write SecretStorage token |

## CI & publishing

- **CI** (`.github/workflows/ci.yml`): pytest + extension compile on push/PR
- **Release** (`.github/workflows/release.yml`): tag `v*` → package `.vsix`, create GitHub Release with attachment; publish to Marketplace / Open VSX only when `VSCE_PAT` / `OVSX_PAT` secrets are set

See [`RELEASE.md`](RELEASE.md) and [`extension/PUBLISH.md`](extension/PUBLISH.md). Package locally:

```bash
cd extension && npm run compile && npm run package
# → creer-1.1.0.vsix (includes media/icon.png)
```

Signed Marketplace / Open VSX publish requires your own `VSCE_PAT` / `OVSX_PAT` (never commit tokens). Agents cannot set GitHub Actions secrets — that remains a human step.

## License

MIT
58 changes: 58 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Releasing Creer v1.0.0

Exact steps for a human maintainer to cut a tagged release with GitHub Release + optional Marketplace / Open VSX publish.

## 1. Set repository secrets (once)

In GitHub → **Settings → Secrets and variables → Actions**, add:

| Secret | Purpose |
|---|---|
| `VSCE_PAT` | Azure DevOps PAT with Marketplace **Acquire** + **Publish** (publisher must match `extension/package.json` → `publisher`) |
| `OVSX_PAT` | Open VSX access token from [open-vsx.org](https://open-vsx.org/) |

Both are optional. If neither is set, the release workflow still builds the `.vsix`, uploads it as an artifact, and (on tag pushes) creates a **GitHub Release** with the `.vsix` attached. Marketplace / Open VSX publish is skipped with `No publish tokens configured — artifact only`.

Never commit PATs. Prefer repo secrets over exporting tokens in shared shells.

**Note:** Cloud agents cannot configure GitHub Actions secrets — a human must set `VSCE_PAT` / `OVSX_PAT` before signed Marketplace / Open VSX publish.

## 2. Bump & verify locally

```bash
# Confirm extension version is 1.0.0
grep '"version"' extension/package.json

cd extension
npm ci
npm run compile
npm run package
# → creer-1.0.0.vsix
```

Smoke-test: `code --install-extension creer-1.0.0.vsix` (or Cursor equivalent) against a running backend.

## 3. Tag v1.0.0 and push

From a clean `main` (or the release commit):

```bash
git tag -a v1.0.0 -m "Creer v1.0.0"
git push origin v1.0.0
```

Tag pattern `v*` triggers [`.github/workflows/release.yml`](.github/workflows/release.yml).

## 4. What the workflow does

1. **build** — `npm ci` → `compile` → `vsce package` → upload `creer-vsix` artifact
2. **github-release** (tag pushes only) — create a GitHub Release and attach the `.vsix` (`contents: write`)
3. **publish** — if `VSCE_PAT` / `OVSX_PAT` secrets exist, publish to Marketplace / Open VSX; otherwise artifact-only

You can also run the workflow via **Actions → Release → Run workflow** (`workflow_dispatch`) for a package/artifact without a tag (no GitHub Release job in that case).

## 5. After release

- Confirm the GitHub Release page lists `creer-1.0.0.vsix`
- If secrets were set, confirm Marketplace / Open VSX listing updated to 1.0.0
- See [`extension/PUBLISH.md`](extension/PUBLISH.md) for manual `vsce` / `ovsx` publish from a laptop
Loading
Loading