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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
node-version: [18, 20, 22]
node-version: [20, 22]

steps:
- uses: actions/checkout@v4
Expand Down
223 changes: 223 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
name: Release

on:
workflow_dispatch:
inputs:
bump:
description: "patch: bug fixes (0.1.0→0.1.1) | minor: new features (0.1.0→0.2.0) | major: breaking changes (0.1.0→1.0.0)"
type: choice
default: "patch"
options:
- patch
- minor
- major
release_core:
description: "Release @mondaycom/hatcha-core"
type: boolean
default: true
release_server:
description: "Release @mondaycom/hatcha-server"
type: boolean
default: true
release_react:
description: "Release @mondaycom/hatcha-react"
type: boolean
default: true

permissions:
contents: write
id-token: write

concurrency:
group: release
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: pnpm
registry-url: "https://registry.npmjs.org"

- run: pnpm install --frozen-lockfile

- name: Validate selection
env:
RELEASE_CORE: ${{ inputs.release_core }}
RELEASE_SERVER: ${{ inputs.release_server }}
RELEASE_REACT: ${{ inputs.release_react }}
run: |
if [[ "$RELEASE_CORE" != "true" && \
"$RELEASE_SERVER" != "true" && \
"$RELEASE_REACT" != "true" ]]; then
echo "::error::No packages selected for release"
exit 1
fi
if [[ "$RELEASE_CORE" != "true" ]]; then
if [[ "$RELEASE_SERVER" == "true" || "$RELEASE_REACT" == "true" ]]; then
echo "::error::Cannot release server/react without core. Core must be included to ensure dependency versions are correct."
exit 1
fi
fi

- name: Bump versions
id: versions
env:
BUMP: ${{ inputs.bump }}
RELEASE_CORE: ${{ inputs.release_core }}
RELEASE_SERVER: ${{ inputs.release_server }}
RELEASE_REACT: ${{ inputs.release_react }}
run: |
if [[ "$RELEASE_CORE" == "true" ]]; then
cd packages/core
NEW_VERSION=$(npm version "$BUMP" --no-git-tag-version)
echo "core_version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
echo "Core bumped to ${NEW_VERSION}"
cd ../..
fi

if [[ "$RELEASE_SERVER" == "true" ]]; then
cd packages/server
NEW_VERSION=$(npm version "$BUMP" --no-git-tag-version)
echo "server_version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
echo "Server bumped to ${NEW_VERSION}"
cd ../..
fi

if [[ "$RELEASE_REACT" == "true" ]]; then
cd packages/react
NEW_VERSION=$(npm version "$BUMP" --no-git-tag-version)
echo "react_version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
echo "React bumped to ${NEW_VERSION}"
cd ../..
fi

- name: Update lockfile
run: pnpm install --no-frozen-lockfile

- name: Build
run: pnpm build

- name: Test
run: pnpm test

- name: Typecheck
run: pnpm typecheck

- name: Publish core
if: inputs.release_core
run: pnpm --filter @mondaycom/hatcha-core publish --no-git-checks --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish server
if: inputs.release_server
run: pnpm --filter @mondaycom/hatcha-server publish --no-git-checks --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish react
if: inputs.release_react
run: pnpm --filter @mondaycom/hatcha-react publish --no-git-checks --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Commit and tag
env:
CORE_VERSION: ${{ steps.versions.outputs.core_version }}
SERVER_VERSION: ${{ steps.versions.outputs.server_version }}
REACT_VERSION: ${{ steps.versions.outputs.react_version }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

git add packages/*/package.json pnpm-lock.yaml

MSG="release [skip ci]:"
TAGS=()

if [[ -n "$CORE_VERSION" ]]; then
MSG="${MSG} core@${CORE_VERSION}"
TAGS+=("@mondaycom/hatcha-core@${CORE_VERSION}")
fi
if [[ -n "$SERVER_VERSION" ]]; then
MSG="${MSG} server@${SERVER_VERSION}"
TAGS+=("@mondaycom/hatcha-server@${SERVER_VERSION}")
fi
if [[ -n "$REACT_VERSION" ]]; then
MSG="${MSG} react@${REACT_VERSION}"
TAGS+=("@mondaycom/hatcha-react@${REACT_VERSION}")
fi

git commit -m "${MSG}"

for TAG in "${TAGS[@]}"; do
git tag "${TAG}"
done

git push origin HEAD --tags --atomic

- name: Create GitHub Releases
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CORE_VERSION: ${{ steps.versions.outputs.core_version }}
SERVER_VERSION: ${{ steps.versions.outputs.server_version }}
REACT_VERSION: ${{ steps.versions.outputs.react_version }}
run: |
LAST_TAG=""

if [[ -n "$CORE_VERSION" ]]; then
LAST_TAG="@mondaycom/hatcha-core@${CORE_VERSION}"
gh release create "$LAST_TAG" \
--title "hatcha-core ${CORE_VERSION}" \
--generate-notes \
--latest=false
fi
if [[ -n "$SERVER_VERSION" ]]; then
LAST_TAG="@mondaycom/hatcha-server@${SERVER_VERSION}"
gh release create "$LAST_TAG" \
--title "hatcha-server ${SERVER_VERSION}" \
--generate-notes \
--latest=false
fi
if [[ -n "$REACT_VERSION" ]]; then
LAST_TAG="@mondaycom/hatcha-react@${REACT_VERSION}"
gh release create "$LAST_TAG" \
--title "hatcha-react ${REACT_VERSION}" \
--generate-notes \
--latest=false
fi

# Mark the last release as "Latest"
if [[ -n "$LAST_TAG" ]]; then
gh release edit "$LAST_TAG" --latest
fi

- name: Summary
env:
CORE_VERSION: ${{ steps.versions.outputs.core_version }}
SERVER_VERSION: ${{ steps.versions.outputs.server_version }}
REACT_VERSION: ${{ steps.versions.outputs.react_version }}
run: |
echo "## Release Summary" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Package | Version |" >> "$GITHUB_STEP_SUMMARY"
echo "|---------|---------|" >> "$GITHUB_STEP_SUMMARY"
if [[ -n "$CORE_VERSION" ]]; then
echo "| @mondaycom/hatcha-core | ${CORE_VERSION} |" >> "$GITHUB_STEP_SUMMARY"
fi
if [[ -n "$SERVER_VERSION" ]]; then
echo "| @mondaycom/hatcha-server | ${SERVER_VERSION} |" >> "$GITHUB_STEP_SUMMARY"
fi
if [[ -n "$REACT_VERSION" ]]; then
echo "| @mondaycom/hatcha-react | ${REACT_VERSION} |" >> "$GITHUB_STEP_SUMMARY"
fi
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.14
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pnpm test
## Code Style

- TypeScript throughout, strict mode.
- No external runtime dependencies in `@hatcha/core`.
- No external runtime dependencies in `@mondaycom/hatcha-core`.
- Keep bundle sizes minimal — the library should stay lightweight.

## License
Expand Down
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</p>

<p align="center">
<a href="https://www.npmjs.com/package/@mondaydotcomorg/hatcha-core"><img src="https://img.shields.io/npm/v/@mondaydotcomorg/hatcha-core" alt="npm" /></a>
<a href="https://www.npmjs.com/package/@mondaycom/hatcha-core"><img src="https://img.shields.io/npm/v/@mondaycom/hatcha-core" alt="npm" /></a>
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License" /></a>
<a href="https://github.com/mondaycom/HATCHA/actions"><img src="https://github.com/mondaycom/HATCHA/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
</p>
Expand All @@ -28,14 +28,14 @@ HATCHA (**H**yperfast **A**gent **T**est for **C**omputational **H**euristic **A
### 1. Install

```bash
npm install @mondaydotcomorg/hatcha-react @mondaydotcomorg/hatcha-server
npm install @mondaycom/hatcha-react @mondaycom/hatcha-server
```

### 2. Add the API route

```typescript
// app/api/hatcha/[...hatcha]/route.ts
import { createHatchaHandler } from "@mondaydotcomorg/hatcha-server/nextjs";
import { createHatchaHandler } from "@mondaycom/hatcha-server/nextjs";

const handler = createHatchaHandler({
secret: process.env.HATCHA_SECRET!,
Expand All @@ -49,8 +49,8 @@ export const POST = handler;

```tsx
// app/layout.tsx
import { HatchaProvider } from "@mondaydotcomorg/hatcha-react";
import "@mondaydotcomorg/hatcha-react/styles.css";
import { HatchaProvider } from "@mondaycom/hatcha-react";
import "@mondaycom/hatcha-react/styles.css";

export default function RootLayout({ children }) {
return (
Expand All @@ -67,7 +67,7 @@ export default function RootLayout({ children }) {

```tsx
"use client";
import { useHatcha } from "@mondaydotcomorg/hatcha-react";
import { useHatcha } from "@mondaycom/hatcha-react";

function AgentModeButton() {
const { requestVerification } = useHatcha();
Expand Down Expand Up @@ -133,7 +133,7 @@ The answer **never** reaches the client. The signed token is opaque and contains
## Custom challenges

```typescript
import { registerChallenge } from "@mondaydotcomorg/hatcha-server";
import { registerChallenge } from "@mondaycom/hatcha-server";

registerChallenge({
type: "hex",
Expand Down Expand Up @@ -176,7 +176,7 @@ Pass `theme="dark"`, `theme="light"`, or `theme="auto"` to `<HatchaProvider>` or

```typescript
import express from "express";
import { hatchaRouter } from "@mondaydotcomorg/hatcha-server/express";
import { hatchaRouter } from "@mondaycom/hatcha-server/express";

const app = express();
app.use(express.json());
Expand All @@ -189,9 +189,9 @@ app.listen(3000);

| Package | Description |
|---------|-------------|
| [`@mondaydotcomorg/hatcha-core`](./packages/core) | Challenge generation and cryptographic verification |
| [`@mondaydotcomorg/hatcha-react`](./packages/react) | React component, provider, and styles |
| [`@mondaydotcomorg/hatcha-server`](./packages/server) | Next.js and Express server handlers |
| [`@mondaycom/hatcha-core`](./packages/core) | Challenge generation and cryptographic verification |
| [`@mondaycom/hatcha-react`](./packages/react) | React component, provider, and styles |
| [`@mondaycom/hatcha-server`](./packages/server) | Next.js and Express server handlers |

## Development

Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs-app/app/api/hatcha/challenge/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createChallenge } from "@mondaydotcomorg/hatcha-core";
import { createChallenge } from "@mondaycom/hatcha-core";

export async function GET() {
const payload = await createChallenge({
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs-app/app/api/hatcha/verify/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { verifyAnswer } from "@mondaydotcomorg/hatcha-core";
import { verifyAnswer } from "@mondaycom/hatcha-core";

export async function POST(request: Request) {
const body = await request.json();
Expand Down
4 changes: 2 additions & 2 deletions examples/nextjs-app/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Metadata } from "next";
import { HatchaProvider } from "@mondaydotcomorg/hatcha-react";
import "@mondaydotcomorg/hatcha-react/styles.css";
import { HatchaProvider } from "@mondaycom/hatcha-react";
import "@mondaycom/hatcha-react/styles.css";
import "./globals.css";

export const metadata: Metadata = {
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs-app/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import { useState } from "react";
import { useHatcha } from "@mondaydotcomorg/hatcha-react";
import { useHatcha } from "@mondaycom/hatcha-react";

export default function Home() {
const { requestVerification } = useHatcha();
Expand Down
6 changes: 3 additions & 3 deletions examples/nextjs-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"start": "next start"
},
"dependencies": {
"@mondaydotcomorg/hatcha-core": "workspace:*",
"@mondaydotcomorg/hatcha-react": "workspace:*",
"@mondaydotcomorg/hatcha-server": "workspace:*",
"@mondaycom/hatcha-core": "workspace:*",
"@mondaycom/hatcha-react": "workspace:*",
"@mondaycom/hatcha-server": "workspace:*",
"next": "^15",
"react": "^19",
"react-dom": "^19"
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@mondaydotcomorg/hatcha-core",
"name": "@mondaycom/hatcha-core",
"version": "0.1.0",
"description": "Challenge generation and cryptographic verification for HATCHA",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/__tests__/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("createChallenge", () => {
expect(typeof challenge.prompt).toBe("string");
expect(typeof challenge.timeLimit).toBe("number");
expect(challenge.timeLimit).toBeGreaterThan(0);
expect((challenge as Record<string, unknown>).answer).toBeUndefined();
expect("answer" in challenge).toBe(false);
expect(typeof token).toBe("string");
expect(token).toContain(".");
});
Expand Down
Loading