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
30 changes: 26 additions & 4 deletions .github/workflows/publish-skills.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,43 @@ on:
workflow_dispatch:

permissions:
contents: write
contents: read

jobs:
review:
runs-on: ubuntu-latest
env:
TESSL_AUTO_UPDATE_INTERVAL_MINUTES: "0"
TESSL_THRESHOLD: "90"
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 24

- name: Review skills with Tessl
run: ./scripts/skills/review.sh

publish:
needs: review
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Set up Tessl
uses: tesslio/setup-tessl@v2
uses: tesslio/setup-tessl@25ec223fc0da33b41b8044ff5ab2b85235f4f91e # v2
with:
token: ${{ secrets.TESSL_TOKEN }}

- name: Publish changed tiles
uses: uinaf/tessl-publish-action@v2.0.0
uses: uinaf/tessl-publish-action@4e224c708ac4253ed901ef9125bccfa73a9cd5ba # v2.0.0
with:
review-threshold: "90"
24 changes: 18 additions & 6 deletions docs/distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,36 @@ jq -r '.name' skills/*/tile.json
## How publishing works

- Each skill directory under `skills/*` has its own `tile.json`
- `.github/workflows/publish-skills.yml` lints and publishes only the tiles that changed on pushes to `main`
- If the workflow is run manually, it publishes all tiles
- The publish workflow uses [`uinaf/tessl-publish-action`](https://github.com/uinaf/tessl-publish-action) to detect changed tiles, run review and lint, and publish them
- `.github/workflows/publish-skills.yml` runs a secretless review job first, then publishes only after the `release` Environment approves the publish job
- Pushes to `main` publish only the tiles that changed
- Manual workflow runs publish all tiles only when the run ref is `main`; non-`main` manual runs can review, but the publish job is skipped
- The publish job uses [`uinaf/tessl-publish-action`](https://github.com/uinaf/tessl-publish-action) to detect changed tiles, run review and lint, and publish them
- The action derives semantic version bumps from Conventional Commit messages: breaking changes -> `major`, `feat` -> `minor`, everything else -> `patch`
- Before publish, the action probes `tessl tile publish --dry-run` and keeps bumping patch versions in the job workspace until Tessl accepts a free version
- After a successful publish, the workflow commits the resulting `tile.json` version bumps back to `main` as `github-actions[bot]` with a skip-CI commit message
- The workflow expects a repository secret named `TESSL_TOKEN`
- Publish-path actions are pinned to full commit SHAs with trailing comments for their human version tags

## Required GitHub secret
## Required GitHub Environment

Create a Tessl API key for the `uinaf` workspace, then add it to this repository as the `TESSL_TOKEN` Actions secret.
Create a GitHub Environment named `release` for the publish job:

- Add a required reviewer who is not the release author
- Enable prevent self-review
- Limit Environment deployment branches to `main`
- Store the Tessl publish token as the Environment secret `TESSL_TOKEN`; do not store it as a plain repository Actions secret
- Protect `main` so only trusted uinaf admins can update it, with force-push and branch deletion blocked where GitHub supports those controls
- If publish or release tags are added later, restrict tag creation and mutation to trusted release automation or release admins

Create a Tessl API key for the `uinaf` workspace, then add it to the `release` Environment as `TESSL_TOKEN`. Use a `uinaf` workspace key, not a token from another Tessl workspace.

You can create the key either from the Tessl web UI or with the CLI:

```bash
npx tessl api-key create --workspace uinaf --name github-actions-publish --role publisher
```

The workflow still references the token as `${{ secrets.TESSL_TOKEN }}`; GitHub resolves that value from the `release` Environment after reviewer approval.

## Local checks

```bash
Expand Down
2 changes: 1 addition & 1 deletion scripts/sync/skills.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"source": "uinaf/agents"
},
{
"name": "viteplus",
"name": "vite-plus",
"source": "uinaf/agents"
}
]
Expand Down
2 changes: 1 addition & 1 deletion skills/gh-release-pipeline/references/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Pick one matching the repo's toolchain and place it after `actions/checkout`. Th
```

```yaml
# Node via VitePlus
# Node via Vite+
- uses: voidzero-dev/setup-vp@v1
with: { node-version-file: ".node-version", cache: true }
- run: vp install
Expand Down
4 changes: 2 additions & 2 deletions skills/uinaf-design-system/references/repo-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ Most uinaf projects ship under MIT. The `LICENSE` file is the canonical text; `R

## Verify and delivery — the short version

The detailed model lives in other skills (`viteplus`, `agent-readiness`, `gh-release-pipeline`, and `gh-deploy-pipeline`). uinaf's expectations at the repo-doc level:
The detailed model lives in the Vite+ skill, plus `agent-readiness`, `gh-release-pipeline`, and `gh-deploy-pipeline`. uinaf's expectations at the repo-doc level:

- One repo-local `verify` entrypoint (`pnpm verify` for TypeScript) that gates everything.
- Every merge to `main` is assumed publishable or deployable. Document the publish path in `CONTRIBUTING.md` so contributors aren't surprised when their merged commit ships.
- Conventional Commits for commit messages. `feat`, `fix`, `docs`, `refactor`, `chore`, `test`, `ci`, `build`. Breaking changes marked with `!` or a `BREAKING CHANGE:` footer.
- VitePlus is the default toolchain for new TypeScript repos. Drive `vp` per package, `pnpm` workspace-wide. Don't invoke `vite` or `vitest` directly.
- Vite+ is the default toolchain for new TypeScript repos. Drive `vp` per package, `pnpm` workspace-wide. Don't invoke `vite` or `vitest` directly.

If the repo can't currently boot, verify, or deliver autonomously, that's an `agent-readiness` problem, not a docs problem — but the docs should reflect reality, not aspiration.

Expand Down
22 changes: 11 additions & 11 deletions skills/viteplus/SKILL.md → skills/vite-plus/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
---
name: viteplus
description: "Migrate or align frontend repositories to the stock VitePlus workflow. Use when standardizing package or monorepo repos around `vp`, `voidzero-dev/setup-vp`, `vite-plus/test`, and VitePlus-native CI, test, packaging, and hook flows. Default to replacing direct package-manager and Vitest wiring with the VitePlus equivalents unless the repo has a proven exception."
name: vite-plus
description: "Migrate or align frontend repositories to the stock Vite+ workflow. Use when standardizing package or monorepo repos around `vp`, `voidzero-dev/setup-vp`, `vite-plus/test`, and Vite+ native CI, test, packaging, and hook flows. Default to replacing direct package-manager and Vitest wiring with the Vite+ equivalents unless the repo has a proven exception."
---

# VitePlus
# Vite+

Move a frontend repo closer to the stock VitePlus toolchain without blindly deleting repo-specific release or runtime logic. VitePlus is in alpha — verify behavior against installed `vp --version` and the latest [release notes](https://github.com/voidzero-dev/vite-plus/releases) rather than memorized command shapes.
Move a frontend repo closer to the stock Vite+ toolchain without blindly deleting repo-specific release or runtime logic. Vite+ is in alpha — verify behavior against installed `vp --version` and the latest [release notes](https://github.com/voidzero-dev/vite-plus/releases) rather than memorized command shapes.

## Migration Targets

Default to this destination unless a repo-specific boundary clearly blocks it. If you keep an old command shape, document the reason.

- CI uses `voidzero-dev/setup-vp@v1`; the action owns Node and package-manager bootstrap, then runs `vp install`, `vp check`, `vp test`, `vp build`
- test files use `vite-plus/test` (and `vite-plus/test/browser/context` for browser mode)
- scripts prefer `vp test`, `vp test watch`, `vp test run --coverage`, `vp pack`, `vp build`, `vp update`, and `vp run <script>` (or `vpr <script>`) over direct package-manager, raw Vitest, or tsdown wiring
- scripts prefer `vp dev`, `vp test`, `vp test watch`, `vp test run --coverage`, `vp pack`, `vp build`, `vp preview`, `vp update`, and `vp run <script>` (or `vpr <script>`) over direct package-manager, raw Vitest, or tsdown wiring
- hooks use `vp config`, `.vite-hooks`, and `vp staged` instead of custom Husky or `lint-staged`
- single-source config in `vite.config.ts`: no parallel `vitest.config.ts`, `.oxlintrc*`, `.oxfmtrc*`, or `tsdown.config.ts`
- contributor docs move to the new `vp` commands in the same change

## Workflow

1. Confirm the project is on Vite 8+ and Vitest 4.1+ — VitePlus refuses older versions.
1. Confirm the project is on Vite 8+ and Vitest 4.1+ — Vite+ refuses older versions.
2. Audit current scripts, workflows, Vite config, test imports, release flow, package manager, and packaging.
3. Read [references/bootstrap.md](references/bootstrap.md) for entrypoints (`vp create`, `vp migrate`), local guidance-file discovery, and validation path.
3. Read [references/bootstrap.md](references/bootstrap.md) for entrypoints (`vp create`, `vp migrate`), editor/agent config, local guidance-file discovery, and validation path.
4. Pick the shape and load only that reference: [references/packages.md](references/packages.md) for standalone packages, or [references/monorepos.md](references/monorepos.md) for workspaces.
5. Migrate scripts, `vite.config.ts`, test imports, hooks, and packaging together. Verify with `vp check && vp test` before moving on.
6. Update CI per [references/ci-cd.md](references/ci-cd.md).
7. Update tests and coverage per [references/testing.md](references/testing.md).
8. Check [references/commands.md](references/commands.md) before changing command invocations. Load [references/known-issues.md](references/known-issues.md) only on unexpected behavior or when upgrading VitePlus.
8. Check [references/commands.md](references/commands.md) before changing command invocations. Load [references/known-issues.md](references/known-issues.md) only on unexpected behavior or when upgrading Vite+.
9. Keep repo-specific release, binary, or packaging steps Vite+ does not replace.
10. To adopt a newer Vite+ release: `vp upgrade` (global), then `vp update vite-plus @voidzero-dev/vite-plus-core @voidzero-dev/vite-plus-test` (project). Confirm with `vp outdated`.
11. End-to-end validation: `vp env current && vp install && vp check && vp test`, then verify `vp build` artifacts, `vp test run --coverage`, and `vp staged` on a staged change.
11. End-to-end validation: `vp env current && vp install && vp check && vp test`, then verify `vp build` or `vp pack` artifacts, `vp preview` where applicable, `vp test run --coverage`, and `vp staged` on a staged change.

Concrete examples:

Expand Down Expand Up @@ -70,8 +70,8 @@ export default defineConfig({

- Prefer `vp create` / `vp migrate --agent <name> --editor <name>` over hand-rolling agent or editor config.
- Do not delete release workflows, binary packaging, or publish steps just to look more "stock."
- If `vp check` is not running type-aware lint or type checks, confirm `lint.options.typeAware` and `lint.options.typeCheck` in `vite.config.ts`, and check for `compilerOptions.baseUrl` in `tsconfig.json` — `tsgolint` does not support `baseUrl` and VitePlus silently skips type-aware checks when it is present.
- If `vp check` is not running type-aware lint or type checks, confirm `lint.options.typeAware` and `lint.options.typeCheck` in `vite.config.ts`, and check for `compilerOptions.baseUrl` in `tsconfig.json` — `tsgolint` does not support `baseUrl` and Vite+ silently skips type-aware checks when it is present.

## Known Caveats

See [references/known-issues.md](references/known-issues.md) for current upstream caveats (hook runners, single-file `vp check --fix`, SSR `instanceof` failures, Cloudflare Workers tests, `@vitest/coverage-v8` mixed-version warnings).
See [references/known-issues.md](references/known-issues.md) for current upstream caveats (single-file `vp check --fix`, SSR `instanceof` failures, Cloudflare Workers tests, `@vitest/coverage-v8` mixed-version warnings).
21 changes: 21 additions & 0 deletions skills/vite-plus/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
interface:
display_name: "Vite+"
short_description: "Align repos with stock Vite+"
default_prompt: |
Use $vite-plus.

Goal: migrate or align a frontend repo with the stock Vite+ workflow.

Success criteria:
- Scripts, tests, config, CI, hooks, and packaging use paths owned by Vite+ where the repo can support them.
- Repo-specific release, binary, or runtime logic is preserved when Vite+ does not replace it cleanly.
- The installed Vite+ behavior is verified before relying on memorized command shapes.

Constraints:
- Do not delete working release or packaging logic just to look stock.
- Do not migrate unsupported Vite or Vitest versions without surfacing the blocker.
- Inspect local guidance files before changing workflows.

Output: no conversational opener. Use bullet labels only: files changed, Vite+ shape, evidence, exceptions, and next. Summarize passing commands by intent/result instead of printing full command strings; include full commands only for failures, reproduction, or when asked.

Stop rules: block when required Vite+ version support, repo package shape, or command behavior cannot be verified.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"context": "Tests whether the agent correctly migrates GitHub Actions CI to the VitePlus-native setup, using the right setup action and install commands, while preserving release steps and using vp run for repo-specific scripts.",
"context": "Tests whether the agent correctly migrates GitHub Actions CI to the Vite+ native setup, using the right setup action and install commands, while preserving release steps and using vp run for repo-specific scripts.",
"type": "weighted_checklist",
"checklist": [
{
Expand All @@ -25,7 +25,7 @@
{
"name": "vp run for custom scripts",
"max_score": 10,
"description": "Any repo-specific scripts not replaced by VitePlus built-ins are invoked via `vp run <script>` (or the `vpr <script>` shorthand) rather than `pnpm run` or `npm run`"
"description": "Any repo-specific scripts not replaced by Vite+ built-ins are invoked via `vp run <script>` (or the `vpr <script>` shorthand) rather than `pnpm run` or `npm run`"
},
{
"name": "No direct package manager commands",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Problem/Feature Description

The `@acme/utils` team maintains a TypeScript utility library used across several internal products. Their GitHub Actions setup was written before VitePlus was adopted and still uses a hand-rolled Node bootstrapping pattern: they install Corepack, activate pnpm through it, and run `pnpm install` manually before running tests with a direct vitest invocation. The CI also includes a separate release workflow that handles npm publishing and creating GitHub releases.
The `@acme/utils` team maintains a TypeScript utility library used across several internal products. Their GitHub Actions setup was written before Vite+ was adopted and still uses a hand-rolled Node bootstrapping pattern: they install Corepack, activate pnpm through it, and run `pnpm install` manually before running tests with a direct vitest invocation. The CI also includes a separate release workflow that handles npm publishing and creating GitHub releases.

The team has since fully adopted VitePlus as their toolchain. Their tech lead wants to standardize CI to match the current toolchain and reduce maintenance overhead — ideally by trimming the bootstrap boilerplate — while making sure nothing in the release process breaks.
The team has since fully adopted Vite+ as their toolchain. Their tech lead wants to standardize CI to match the current toolchain and reduce maintenance overhead — ideally by trimming the bootstrap boilerplate — while making sure nothing in the release process breaks.

## Output Specification

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"context": "Tests whether the agent correctly consolidates a project's fragmented configuration files into a single vite.config.ts following VitePlus conventions, enables type-aware lint options, and handles the baseUrl incompatibility with VitePlus type-aware checks that causes silent failures.",
"context": "Tests whether the agent correctly consolidates a project's fragmented configuration files into a single vite.config.ts following Vite+ conventions, enables type-aware lint options, and handles the baseUrl incompatibility with Vite+ type-aware checks that causes silent failures.",
"type": "weighted_checklist",
"checklist": [
{
Expand Down Expand Up @@ -30,7 +30,7 @@
{
"name": "baseUrl incompatibility addressed",
"max_score": 15,
"description": "The `compilerOptions.baseUrl` is either removed from `tsconfig.json` OR the output explicitly documents that `baseUrl` causes VitePlus to silently skip type-aware checks and recommends removing it"
"description": "The `compilerOptions.baseUrl` is either removed from `tsconfig.json` OR the output explicitly documents that `baseUrl` causes Vite+ to silently skip type-aware checks and recommends removing it"
},
{
"name": "Staged config in vite.config.ts",
Expand Down
Loading