Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
702f774
Merge pull request #3 from agenticaihome/master
0xf965 Mar 31, 2026
8eec029
Update README.md
0xf965 Mar 31, 2026
715b769
fix: calculateHashFromUrl uses selected algorithm + chunked support
agenticaihome Apr 1, 2026
a7ca732
Merge pull request #4 from agenticaihome/fix/hash-algorithm-chunked
0xf965 Apr 3, 2026
254b855
feat: hash validation toggle in settings + fallback profile detection
agenticaihome Apr 3, 2026
8f5b8bb
Merge pull request #5 from agenticaihome/fix/settings-hash-toggle-and…
0xf965 Apr 3, 2026
137a2e6
fix: accept any profile type for detection, not just PROFILE_TYPE_NFT_ID
agenticaihome Apr 4, 2026
76eddec
Merge pull request #6 from agenticaihome/fix/accept-any-profile-type
0xf965 Apr 4, 2026
b9cbf17
feat: add GitHub Pages deployment with dynamic base path and esRawPlugin
agenticaihome Apr 4, 2026
581f24c
Merge pull request #7 from agenticaihome/feat/github-pages-deploy
0xf965 Apr 4, 2026
f195df9
feat: export all library components (SearchByHash, ProfileSources, Ti…
agenticaihome Apr 6, 2026
8d67d82
Merge pull request #8 from agenticaihome/feat/export-all-library-comp…
0xf965 Apr 6, 2026
257556a
build: package updated library with hash function, format fields, and…
agenticaihome Apr 7, 2026
8c9c85e
Merge pull request #9 from agenticaihome/feat/export-all-library-comp…
0xf965 Apr 7, 2026
afc0de2
ci: auto-build dist on push to master
agenticaihome Apr 7, 2026
5c9ae48
improved library - fixed mode, no hash function id
0xf965 Apr 8, 2026
5b1bdd4
fixed hash function usage
0xf965 Apr 8, 2026
f949efe
dist
0xf965 Apr 8, 2026
9ca1e12
wallet lib
0xf965 Apr 22, 2026
b23c78d
wallet lib
0xf965 Apr 22, 2026
04b9fd5
fixed profile loading with url
0xf965 Apr 22, 2026
ff0ff44
updated fixed hash id
0xf965 Apr 22, 2026
bda233b
fixed
0xf965 Apr 24, 2026
cfd3aac
fixed all user profiles usage
0xf965 Apr 24, 2026
3207c1b
fixed file source creation
0xf965 Apr 24, 2026
2e03fda
simplified file card
0xf965 Jun 23, 2026
04bd30c
package log rebuild
0xf965 Jun 23, 2026
e03dfa1
feat: full-surface MCP server + Celaut .service (MCP HTTP + REST)
agenticaihome Jun 27, 2026
8c78ab7
deps: pin reputation-system to upstream master instead of agenticaiho…
agenticaihome Jun 27, 2026
83c9406
Merge remote-tracking branch 'origin/master' into feat/celaut-mcp-ser…
agenticaihome Jun 27, 2026
e0ec9dd
refactor(mcp): reuse src for reads via esbuild bundle; dedup mcp/.ser…
agenticaihome Jun 27, 2026
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
43 changes: 17 additions & 26 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy to GitHub Pages & Package
name: Deploy to GitHub Pages

on:
push:
Expand All @@ -11,41 +11,32 @@ permissions:
id-token: write

concurrency:
group: pages
cancel-in-progress: true
group: "pages"
cancel-in-progress: false

jobs:
build-and-deploy:
build:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Build site
run: npm run build
- run: npm ci
- run: npm run build
env:
NODE_ENV: production

- name: Package library
run: npm run package

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
- uses: actions/upload-pages-artifact@v3
with:
path: build

- name: Deploy to GitHub Pages
id: deployment
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
42 changes: 42 additions & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Build & commit dist

on:
push:
branches: [master]
paths:
- 'src/lib/**'
- 'package.json'
- 'package-lock.json'
- 'svelte.config.js'
- 'tsconfig.json'

permissions:
contents: write

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

- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- run: npm ci
- run: npm run package

- name: Commit dist if changed
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add dist/
if git diff --cached --quiet; then
echo "No dist changes to commit"
else
git commit -m "build: auto-package dist [skip ci]"
git push
fi
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ yarn-error.log
*.apk
.metals/
.scala-build/
.test.scala
.test.scala
.codex
37 changes: 37 additions & 0 deletions .service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Celaut builds this image only to export its filesystem (docker buildx
# --output type=tar); the container is never run directly. CMD/ENTRYPOINT,
# EXPOSE and runtime ENV are intentionally omitted — the entrypoint, ports and
# envs are declared in service.json.
#
# Build context is the repository root (the packer moves this Dockerfile into
# .service/ and rewrites `./` COPY paths to `service/...`). Non-`./` paths such
# as `mcp` are left as-is and resolve against the repo root, so the sealed VM can
# bundle the SINGLE shared registry that lives in mcp/ — no duplicated copies.
#
# Image layout mirrors the repo so `../mcp` imports in service/server-http.mjs
# resolve the same way inside the VM as in local dev:
# /app/service/server-http.mjs (this .service)
# /app/mcp/... (shared core/lib/writes/tools + prebuilt bundle)
# /app/node_modules (production deps from .service/package.json)
FROM node:20-slim

WORKDIR /app

# Production deps only (better layer caching: deps before source).
COPY ./package.json /app/package.json
RUN npm install --omit=dev --no-audit --no-fund

# The shared MCP registry (reads bundled from src/, writes, tools) — single source
# of truth. The prebuilt _generated/lib.bundle.mjs is committed, so the VM needs no
# build toolchain. Copy node-only files; the mcp/node_modules + package*.json are
# intentionally excluded (deps come from /app/node_modules above).
COPY mcp/core.mjs /app/mcp/core.mjs
COPY mcp/lib.mjs /app/mcp/lib.mjs
COPY mcp/writes.mjs /app/mcp/writes.mjs
COPY mcp/tools.mjs /app/mcp/tools.mjs
COPY mcp/_generated /app/mcp/_generated

# This service: HTTP+REST server + init wrapper.
COPY ./server-http.mjs /app/service/server-http.mjs
COPY ./start.sh /app/start.sh
RUN chmod +x /app/start.sh
97 changes: 97 additions & 0 deletions .service/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Source Application — Celaut Service (MCP + REST)

A sealed Celaut microVM that exposes the **full** Source Application on-chain
file-source registry surface over plain HTTP on `0.0.0.0:8080`:

- `GET /health` — liveness probe.
- `* /mcp` — the complete MCP tool surface (Streamable HTTP transport), identical
to the stdio server in [`../mcp/`](../mcp).
- `* /api/*` — a clean JSON REST mirror of every method (reads via `GET`, writes
via `POST`).

Reads + pure helpers, writes, the env-configured signer, and the shared MCP tool
registry all live **once** under [`../mcp/`](../mcp); `server-http.mjs` imports
them directly (`../mcp/core.mjs`, `lib.mjs`, `writes.mjs`, `tools.mjs`) — there
are no duplicated copies in `.service/`. The MCP and REST layers call the same
functions, so they never diverge, and the on-chain read logic itself is bundled
from `src/` (see [`../mcp/README.md`](../mcp/README.md)).

The `Dockerfile` preserves this sibling layout inside the sealed microVM
(`/app/service/server-http.mjs` + `/app/mcp/...`) so `../mcp` resolves the same
way in the VM as in local dev. The prebuilt `../mcp/_generated/lib.bundle.mjs` is
copied in, so the VM needs no build toolchain.

## Run locally

```bash
# from ../mcp first: npm install && npm run build:mcp (provides node_modules + bundle)
npm install
npm start # binds 0.0.0.0:8080, imports ../mcp/*
curl localhost:8080/health
```

## Signer modes (env)

Default is **unsigned** — no key ever lives in the VM; writes return an unsigned
EIP-12 transaction for an external wallet (Nautilus/ErgoPay) to sign.

| Mode | Env |
|------------|-------------------------------------------------------------------------------------|
| `unsigned` | `SOURCE_SIGNER_MODE=unsigned`, `SOURCE_ADDRESS=<P2PK address>` (default) |
| `seed` | `SOURCE_SIGNER_MODE=seed`, `SOURCE_MNEMONIC=...`, optional `SOURCE_MNEMONIC_PASSWORD`, `SOURCE_NODE_URI`, `SOURCE_ADDRESS_INDEX` |

Other env: `SOURCE_EXPLORER_API` (default `https://api.ergoplatform.com`),
`PORT` (default `8080`).

## REST routes

Reads (GET):

| Route | Maps to |
|-------|---------|
| `GET /api/config` | type NFT ids + signer mode |
| `GET /api/sources?hash=HASH` | `fetchFileSourcesByHash` |
| `GET /api/sources/by-profile?profileTokenId=ID&limit=N` | `fetchFileSourcesByProfile` |
| `GET /api/sources/:boxId/invalidations` | `fetchInvalidFileSources` |
| `GET /api/unavailable?url=URL` | `fetchUnavailableSources` |
| `GET /api/invalidations/by-profile?profileTokenId=ID&limit=N` | `fetchInvalidFileSourcesByProfile` |
| `GET /api/unavailable/by-profile?profileTokenId=ID&limit=N` | `fetchUnavailableSourcesByProfile` |
| `GET /api/profiles/:profileTokenId/opinions` | `fetchProfileOpinions` |
| `GET /api/profiles/:authorTokenId/opinions-given` | `fetchProfileOpinionsByAuthor` |
| `GET /api/profiles/:profileTokenId` | `loadProfileData` |
| `GET /api/search?hash=HASH` | `searchByHash` |
| `GET /api/hash-algorithms` | `HASH_OPTIONS` |

Writes (POST, signed per `SOURCE_SIGNER_MODE`):

| Route | Body | Maps to |
|-------|------|---------|
| `POST /api/profile` | `{content?}` | `createProfileBox` |
| `POST /api/sources` | `{mainBoxId, fileHash, sourceEntry}` | `addFileSource` |
| `POST /api/sources/confirm` | `{mainBoxId, fileHash, sourceEntry}` | `confirmSource` |
| `POST /api/sources/update` | `{mainBoxId, fileHash, sourceEntry}` | `updateFileSource` (see note) |
| `POST /api/sources/invalidate` | `{mainBoxId, sourceBoxId}` | `markInvalidSource` |
| `POST /api/unavailable` | `{mainBoxId, sourceUrl}` | `markUnavailableSource` |
| `POST /api/profiles/trust` | `{mainBoxId, profileTokenId, isTrusted}` | `trustProfile` |

`sourceEntry` = `{hashFunctionId, contentFormat, contentHash, rawFormat, urlLink, isChunked?}`.

`mainBoxId` is the author's **PROFILE box** id (the box holding their reputation
token); every opinion is split from it.

### Note on `update_file_source`

The original browser flow spends the previous FILE_SOURCE box via
`update_opinion` (a Nautilus-only path). The headless `reputation-system/node`
entry exposes `create_*_with_signer` but **not** `update_opinion_with_signer`, so
here `update_file_source` publishes a **new** FILE_SOURCE opinion carrying the
new content for the same hash; the previous box is left in place (it can be
invalidated separately).

## Type NFT placeholders

`INVALID_FILE_SOURCE_TYPE_NFT_ID`, `UNAVAILABLE_SOURCE_TYPE_NFT_ID`, and
`PROFILE_OPINION_TYPE_NFT_ID` are still PLACEHOLDER (all-zero) values in
`src/lib/ergo/envs.ts`; they are preserved verbatim. Reads against them simply
return empty arrays until the real Type NFTs are minted. `FILE_SOURCE_TYPE_NFT_ID`
and `PROFILE_TYPE_NFT_ID` are real and return live data.
8 changes: 8 additions & 0 deletions .service/pack_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"ignore": [
"node_modules/",
".git/",
"*.celaut",
"*.md"
]
}
Loading