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
140 changes: 140 additions & 0 deletions .github/workflows/vscode-marketplace.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: Publish VS Code Marketplace extension

on:
workflow_dispatch:
inputs:
release_ref:
description: "Immutable repository tag to package (for example v0.28.0)"
required: true
type: string
publish:
description: "Publish the verified VSIX to the VS Code Marketplace after protected-environment review"
required: true
default: false
type: boolean

permissions:
contents: read

concurrency:
group: vscode-marketplace-${{ inputs.release_ref }}
cancel-in-progress: false

jobs:
authorize:
name: authorize protected VS Code publication
if: inputs.publish == true
runs-on: ubuntu-latest
environment: vscode-marketplace
steps:
- name: Require the scoped VS Code publisher token before candidate work
shell: bash
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: |
set -euo pipefail
test -n "$VSCE_PAT" || {
echo "VSCE_PAT is required in the vscode-marketplace environment." >&2
exit 1
}

validate:
name: validate immutable VS Code candidate
needs: authorize
if: ${{ always() && (inputs.publish == false || needs.authorize.result == 'success') }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: editors/vscode
steps:
- uses: actions/checkout@v5
with:
ref: ${{ inputs.release_ref }}
fetch-depth: 0
- name: Require an immutable release tag
shell: bash
env:
RELEASE_REF: ${{ inputs.release_ref }}
run: |
set -euo pipefail
[[ "$RELEASE_REF" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$ ]] || {
echo "release_ref must be an immutable tag such as v0.28.0." >&2
exit 1
}
test "$(git rev-list -n 1 "$RELEASE_REF")" = "$(git rev-parse HEAD)" || {
echo "Checked-out commit does not match $RELEASE_REF." >&2
exit 1
}
git tag --points-at HEAD --format='%(refname:short)' | grep -Fx "$RELEASE_REF" >/dev/null || {
echo "$RELEASE_REF is not an immutable tag pointing at HEAD." >&2
exit 1
}
- uses: actions/setup-node@v7.0.0
with:
node-version: "22"
cache: npm
cache-dependency-path: editors/vscode/package-lock.json
- name: Install, audit, test, and package
run: |
set -euo pipefail
npm ci
npm run audit
npm test
npx vsce package --no-dependencies --out factoryline-vscode.vsix
- name: Seal the verified VS Code candidate
shell: bash
env:
RELEASE_REF: ${{ inputs.release_ref }}
run: |
set -euo pipefail
test -f factoryline-vscode.vsix
mkdir -p "$GITHUB_WORKSPACE/vscode-marketplace-candidate"
cp factoryline-vscode.vsix "$GITHUB_WORKSPACE/vscode-marketplace-candidate/"
sha256sum factoryline-vscode.vsix > "$GITHUB_WORKSPACE/vscode-marketplace-candidate/SHA256SUMS.txt"
printf 'release_ref=%s\ncommit=%s\npublisher=zrk222\n' \
"$RELEASE_REF" "$(git rev-parse HEAD)" > "$GITHUB_WORKSPACE/vscode-marketplace-candidate/manifest.txt"
- uses: actions/upload-artifact@v7.0.1
with:
name: vscode-marketplace-candidate-${{ inputs.release_ref }}
path: vscode-marketplace-candidate/
if-no-files-found: error
retention-days: 14

publish:
name: publish verified VS Code candidate
if: ${{ always() && inputs.publish == true && needs.authorize.result == 'success' && needs.validate.result == 'success' }}
needs: [authorize, validate]
runs-on: ubuntu-latest
environment: vscode-marketplace
steps:
- uses: actions/download-artifact@v8.0.1
with:
name: vscode-marketplace-candidate-${{ inputs.release_ref }}
path: vscode-marketplace-candidate
- name: Require the scoped VS Code publisher token
shell: bash
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: |
set -euo pipefail
test -n "$VSCE_PAT" || {
echo "VSCE_PAT is required in the vscode-marketplace environment." >&2
exit 1
}
- name: Verify sealed candidate
shell: bash
run: |
set -euo pipefail
cd vscode-marketplace-candidate
sha256sum --check SHA256SUMS.txt
test -f manifest.txt
test -f factoryline-vscode.vsix
- name: Publish verified VSIX to VS Code Marketplace
shell: bash
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: |
set -euo pipefail
npx --yes @vscode/vsce@3.2.1 publish \
--packagePath vscode-marketplace-candidate/factoryline-vscode.vsix \
--pat "$VSCE_PAT"
40 changes: 40 additions & 0 deletions .mcp/server.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.zrk222/code-factory",
"title": "Code Factory proof context",
"description": "Read-only Graph Ops and proof context for AI coding clients.",
"version": "0.28.0",
"websiteUrl": "https://zrk222-code-factory.static.hf.space",
"repository": {
"url": "https://github.com/zrk222/code-factory",
"source": "github"
},
"packages": [
{
"registryType": "pypi",
"registryBaseUrl": "https://pypi.org",
"identifier": "factoryline-code-factory",
"version": "0.28.0",
"runtimeHint": "uvx",
"transport": {
"type": "stdio"
},
"runtimeArguments": [
{
"type": "positional",
"value": "factory"
}
],
"packageArguments": [
{
"type": "positional",
"value": "mcp"
},
{
"type": "positional",
"value": "serve"
}
]
}
]
}
41 changes: 37 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# code-factory
# Code Factory

<!-- mcp-name: io.github.zrk222/code-factory -->

[![CI](https://github.com/zrk222/code-factory/actions/workflows/ci.yml/badge.svg)](https://github.com/zrk222/code-factory/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/factoryline-code-factory.svg)](https://pypi.org/project/factoryline-code-factory/)
[![Python](https://img.shields.io/pypi/pyversions/factoryline-code-factory.svg)](https://pypi.org/project/factoryline-code-factory/)
[![Hugging Face Space](https://img.shields.io/badge/Hugging%20Face-Space-ffd21e.svg)](https://huggingface.co/spaces/zrk222/code-factory)
[![GitHub stars](https://img.shields.io/github/stars/zrk222/code-factory?style=social)](https://github.com/zrk222/code-factory/stargazers)
[![Latest release](https://img.shields.io/github/v/release/zrk222/code-factory)](https://github.com/zrk222/code-factory/releases/latest)

> One intent, seven software targets, and proof that the gates reject
> deliberately sabotaged builds.
> Turn a plain-language outcome into a reviewable MVP with deterministic proof—
> without pretending generated code is production-ready.

> **Why pay for opaque app generators?** Create a reviewable MVP starting state
> in minutes—with source-bound receipts, a clear proof path, and an output you
Expand All @@ -21,7 +25,32 @@ factory studio --root .\my-mvp

[Watch the exact shipped UI in 60 seconds](https://github.com/zrk222/code-factory/releases/download/v0.28.0/code-factory-quickstart-v0171.mp4)
to see the outcome-to-MVP path, then open **Graph Ops** in the local Studio to
inspect the evidence path and next action.
inspect the evidence path and next action. Prefer a browser preview? Open the
[live Hugging Face Space](https://zrk222-code-factory.static.hf.space).

**Choose the shortest path:**

| Goal | Start here | What you get |
| --- | --- | --- |
| Create | `factory mvp "..."` | A contained, app-shaped starting state |
| Inspect | `factory studio --root .` | Graph Ops, receipts, and one next action |
| Connect | [Cursor or OpenCode MCP](docs/AI_CLIENTS.md) | Portable, local proof context |
| Prove | `factory verify <feature> --root .` | A fail-closed decision with evidence |

## Verify in GitHub Actions

Use the root composite action when a pull request or release should carry the
same proof decision as a local run:

```yaml
- uses: zrk222/code-factory@v0.28.1
with:
feature: my-feature
```

It uploads the JSON decision and manifest as a workflow artifact, and fails the
job when the evidence is incomplete. See [GitHub Marketplace action](docs/GITHUB_MARKETPLACE_ACTION.md)
for the input contract and publication boundary.

## What Code Factory is

Expand All @@ -33,6 +62,10 @@ gates; then show what is proven, missing, blocked, or safe to do next. Factory
Studio and the editor integrations make the same workflow visible without
granting them release, credential, approval, or publishing authority.

It works with the local workflows developers already use—including Codex,
Claude Code, Cursor, OpenCode, VS Code, and JetBrains—through the same
receipt-bound contract rather than a provider-specific lock-in.

It is designed for two speeds: use `factory mvp "..."` to get a novice from
idea to an inspectable MVP path, or compose capability packs, signed receipts,
proof reuse, Graph Ops impact analysis, and supervised enterprise controls for
Expand Down
70 changes: 70 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Code Factory proof verification
description: Run a fail-closed Code Factory shippability decision and retain its JSON proof artifact.
author: zrk222
branding:
icon: shield
color: green

inputs:
feature:
description: Existing feature id whose local receipts and verifier evidence should be summarized.
required: true
root:
description: Workspace root passed to Code Factory.
required: false
default: .
package-version:
description: Published factoryline-code-factory version to run.
required: false
default: 0.28.0
artifact-name:
description: Artifact name used for the JSON proof output.
required: false
default: code-factory-proof

runs:
using: composite
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install Code Factory
shell: bash
env:
FACTORY_PACKAGE_VERSION: ${{ inputs.package-version }}
run: |
set -euo pipefail
python -m pip install --disable-pip-version-check \
"factoryline-code-factory==${FACTORY_PACKAGE_VERSION}"
- name: Run fail-closed proof decision
shell: bash
env:
FACTORY_FEATURE: ${{ inputs.feature }}
FACTORY_ROOT: ${{ inputs.root }}
run: |
set -euo pipefail
proof_dir="$GITHUB_WORKSPACE/factory-proof"
mkdir -p "$proof_dir"
set +e
factory verify "$FACTORY_FEATURE" --root "$FACTORY_ROOT" --json \
| tee "$proof_dir/verify.json"
status=${PIPESTATUS[0]}
set -e
printf 'exit_code=%s\nfeature=%s\n' "$status" "$FACTORY_FEATURE" \
> "$proof_dir/manifest.txt"
echo "FACTORY_VERIFY_EXIT=$status" >> "$GITHUB_ENV"
exit "$status"
- name: Upload proof artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact-name }}
path: factory-proof/
if-no-files-found: error
- name: Preserve the proof decision as the action result
if: always()
shell: bash
run: |
set -euo pipefail
test "${FACTORY_VERIFY_EXIT:-1}" -eq 0
17 changes: 16 additions & 1 deletion deploy/huggingface/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ tags:
- devops
- software-quality
- mcp
- model-context-protocol
- cursor
- opencode
- local-first
pinned: false
license: apache-2.0
short_description: Reviewable MVPs with verifier, repair, and workspace proof
short_description: Proof-backed AI coding workflows with local MCP context
---

# Code Factory
Expand All @@ -34,6 +37,18 @@ The canonical Python package is
Release `v0.28.0` is archived under the repository's stable Zenodo concept DOI at
[Zenodo](https://doi.org/10.5281/zenodo.21381405).

Use the same local proof context from Cursor or OpenCode through the documented
[MCP connection](https://github.com/zrk222/code-factory/blob/main/docs/AI_CLIENTS.md).
The client connection is local and read-only; it does not upload source or
grant provider, credential, deployment, or publishing authority.

Try the public **Proof Playground** before installing: enter an outcome and
watch a deterministic browser-only preview assemble intent, checks, and a
local proof reference. It is deliberately not a production mission, does not
call a model, and never sends the text away. The same page includes copyable
recipes for repository readiness, contained MVPs, Graph Ops, independent
verification, Cursor, and OpenCode.

Before a PRD becomes a scaffold, run `factory prd grill PRD.md --root .` for a
capped, source-bound clarification sheet with recommendations and answer stubs.
It never rewrites the PRD, invents answers, calls a model, or authorizes a
Expand Down
Loading