The monorepo was on npm workspaces. pnpm gives it a content-addressed store shared between the eight packages, a lockfile that records the whole graph rather than a flattened view of it, and — the reason this mattered in practice — `workspace:*`, which makes an internal dependency unambiguous instead of a version range that npm may satisfy from the registry. Mechanics: - `packageManager: pnpm@11.21.0` pins the version; corepack installs it in CI and in the image, so all three environments resolve identically. - The npm `workspaces` array is replaced by `pnpm-workspace.yaml`. pnpm ignores the former, and keeping both would leave two sources of truth. - All six internal dependencies moved to `workspace:*`. - Root scripts use `pnpm -r --if-present` and `pnpm -F <pkg>`. Two findings worth recording, both from running it rather than reading it: `tsx` was a devDependency, but the server runs TypeScript directly in production — the container's command is `pnpm exec tsx apps/api/src/server.ts`. Under npm this was concealed by the runtime stage re-installing tsx by hand after pruning dev dependencies. Under `pnpm install --prod` that sleight of hand stops working and the image simply fails to start. tsx is now declared in `dependencies`, which is what it has always actually been. The first image build failed with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY. That is not a pnpm bug: it had decided the modules directory was stale and wanted confirmation before deleting it, which a non-interactive build cannot give. The trigger was the host's `node_modules` reaching the build context — there was no `.dockerignore` at all. pnpm's tree is symlinks into a content-addressed store, so copying it into an image produces dangling links and a directory pnpm rightly considers corrupt. Fixed by adding `.dockerignore` and setting `CI=true`, which is required in any non-interactive pnpm build. `esbuild` is denied install scripts via `allowBuilds`. Its platform binary arrives through the optional dependency `@esbuild/linux-x64` and the postinstall only verifies it; confirmed by running the binary directly, which reports 0.25.12. Verified under pnpm: typecheck clean, 150 tests / 0 failures, e2e passes, web builds. The image was built and booted against a real Postgres — health ok, `/api/dashboard` 401 with an issuer configured, `/` and `/capacity` serve the SPA, `/og.png` serves as image/png, and the migrator runs from the pruned runtime stage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
# Keep the build context small and — more importantly — keep the host's
|
||||||
|
# node_modules out of it. pnpm's store is a tree of symlinks into a
|
||||||
|
# content-addressed directory on the host; copying that tree into an image
|
||||||
|
# produces dangling links, and pnpm then decides the modules directory is
|
||||||
|
# corrupt and asks to purge it. In a non-TTY build it cannot ask, so it aborts.
|
||||||
|
node_modules
|
||||||
|
**/node_modules
|
||||||
|
|
||||||
|
# The image installs from the lockfile and builds from source; neither the
|
||||||
|
# history nor prior build output belongs in it.
|
||||||
|
.git
|
||||||
|
.gitea
|
||||||
|
**/dist
|
||||||
|
apps/web/dist
|
||||||
|
|
||||||
|
# Local state that must never be baked into an image.
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
backups
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Test and tooling artefacts.
|
||||||
|
test-results
|
||||||
|
playwright-report
|
||||||
|
**/*.tsbuildinfo
|
||||||
+27
-10
@@ -59,6 +59,19 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: '22'
|
node-version: '22'
|
||||||
|
|
||||||
|
# Corepack ships with Node and installs the exact pnpm pinned by
|
||||||
|
# `packageManager` in package.json, so CI, the image and a laptop all run
|
||||||
|
# the same version. `--activate` puts it on PATH; the download prompt is
|
||||||
|
# disabled because a non-interactive runner cannot answer it and would
|
||||||
|
# otherwise hang until the job times out.
|
||||||
|
- name: Enable pnpm
|
||||||
|
env:
|
||||||
|
COREPACK_ENABLE_DOWNLOAD_PROMPT: '0'
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
corepack prepare --activate
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
- name: Start Postgres
|
- name: Start Postgres
|
||||||
run: |
|
run: |
|
||||||
PG_PORT=$(( 45000 + (${{ github.run_id }} % 15000) ))
|
PG_PORT=$(( 45000 + (${{ github.run_id }} % 15000) ))
|
||||||
@@ -91,38 +104,42 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: npm install --no-audit --no-fund
|
# --frozen-lockfile fails rather than quietly resolving a different
|
||||||
|
# tree when the lockfile and manifests disagree. That is the whole
|
||||||
|
# point of committing a lockfile, and it is the default in CI anyway —
|
||||||
|
# stated here so it survives someone running this locally.
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Typecheck every package
|
- name: Typecheck every package
|
||||||
run: npm run typecheck
|
run: pnpm run typecheck
|
||||||
|
|
||||||
- name: Unit tests
|
- name: Unit tests
|
||||||
run: npm test --workspaces --if-present
|
run: pnpm run test
|
||||||
|
|
||||||
- name: Migrations apply to a real Postgres
|
- name: Migrations apply to a real Postgres
|
||||||
run: npx tsx packages/db/src/migrate.ts
|
run: pnpm exec tsx packages/db/src/migrate.ts
|
||||||
|
|
||||||
- name: Migrations are re-runnable
|
- name: Migrations are re-runnable
|
||||||
run: npx tsx packages/db/src/migrate.ts
|
run: pnpm exec tsx packages/db/src/migrate.ts
|
||||||
|
|
||||||
- name: Seed is idempotent
|
- name: Seed is idempotent
|
||||||
# A seed that duplicates on a second run corrupts any database it is
|
# A seed that duplicates on a second run corrupts any database it is
|
||||||
# pointed at twice, and nobody notices until the counts look odd.
|
# pointed at twice, and nobody notices until the counts look odd.
|
||||||
run: |
|
run: |
|
||||||
npx tsx packages/db/src/seed/index.ts > /dev/null
|
pnpm exec tsx packages/db/src/seed/index.ts > /dev/null
|
||||||
count() { docker exec "$PG_CONTAINER" psql -U pig -d pig -tAc "select count(*) from contacts"; }
|
count() { docker exec "$PG_CONTAINER" psql -U pig -d pig -tAc "select count(*) from contacts"; }
|
||||||
BEFORE=$(count)
|
BEFORE=$(count)
|
||||||
npx tsx packages/db/src/seed/index.ts > /dev/null
|
pnpm exec tsx packages/db/src/seed/index.ts > /dev/null
|
||||||
AFTER=$(count)
|
AFTER=$(count)
|
||||||
echo "contacts: $BEFORE -> $AFTER"
|
echo "contacts: $BEFORE -> $AFTER"
|
||||||
test "$BEFORE" = "$AFTER" || { echo "SEED IS NOT IDEMPOTENT"; exit 1; }
|
test "$BEFORE" = "$AFTER" || { echo "SEED IS NOT IDEMPOTENT"; exit 1; }
|
||||||
|
|
||||||
- name: Critical path E2E against Postgres and Hono
|
- name: Critical path E2E against Postgres and Hono
|
||||||
run: npm run test:e2e
|
run: pnpm run test:e2e
|
||||||
|
|
||||||
- name: Server boots and answers
|
- name: Server boots and answers
|
||||||
run: |
|
run: |
|
||||||
NODE_ENV=development PIG_PORT=8930 npx tsx apps/api/src/server.ts &
|
NODE_ENV=development PIG_PORT=8930 pnpm exec tsx apps/api/src/server.ts &
|
||||||
for i in $(seq 1 30); do
|
for i in $(seq 1 30); do
|
||||||
curl -sf http://127.0.0.1:8930/api/health && break
|
curl -sf http://127.0.0.1:8930/api/health && break
|
||||||
sleep 1
|
sleep 1
|
||||||
@@ -130,7 +147,7 @@ jobs:
|
|||||||
curl -sf http://127.0.0.1:8930/api/health | grep -q '"ok":true'
|
curl -sf http://127.0.0.1:8930/api/health | grep -q '"ok":true'
|
||||||
|
|
||||||
- name: Front end builds
|
- name: Front end builds
|
||||||
run: npm run build -w @pig/web
|
run: pnpm -F @pig/web run build
|
||||||
|
|
||||||
- name: Inline theme script still matches the deployed CSP hash
|
- name: Inline theme script still matches the deployed CSP hash
|
||||||
# The proxy allows exactly one inline script by hash. If the script
|
# The proxy allows exactly one inline script by hash. If the script
|
||||||
|
|||||||
@@ -52,8 +52,15 @@ docs/ ontology.md, build-plan.md, agents.md, deploy.md, seed-data.md
|
|||||||
|
|
||||||
## 3. Running it
|
## 3. Running it
|
||||||
|
|
||||||
|
**PIG uses pnpm**, pinned by the `packageManager` field. Do not run `npm
|
||||||
|
install` — it will write a `package-lock.json` that nothing reads and resolve a
|
||||||
|
dependency tree that neither CI nor the image uses. Corepack ships with Node and
|
||||||
|
installs the pinned version for you:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
corepack enable
|
||||||
|
|
||||||
|
pnpm install
|
||||||
|
|
||||||
# Postgres. PIG needs its own database — never point it at a shared one.
|
# Postgres. PIG needs its own database — never point it at a shared one.
|
||||||
docker run -d --name pig-dev -p 5432:5432 \
|
docker run -d --name pig-dev -p 5432:5432 \
|
||||||
@@ -61,12 +68,12 @@ docker run -d --name pig-dev -p 5432:5432 \
|
|||||||
postgres:16-alpine
|
postgres:16-alpine
|
||||||
|
|
||||||
export DATABASE_URL=postgres://pig:pig@localhost:5432/pig
|
export DATABASE_URL=postgres://pig:pig@localhost:5432/pig
|
||||||
npm run db:migrate
|
pnpm run db:migrate
|
||||||
npm run db:seed # sourced, cited people — optional
|
pnpm run db:seed # sourced, cited people — optional
|
||||||
npm run db:demo # a plausible demo book — optional, prefixed "DEMO — "
|
pnpm run db:demo # a plausible demo book — optional, prefixed "DEMO — "
|
||||||
|
|
||||||
npm run dev:api # :8920
|
pnpm run dev:api # :8920
|
||||||
npm run dev:web # :5173, proxies /api to 8920
|
pnpm run dev:web # :5173, proxies /api to 8920
|
||||||
```
|
```
|
||||||
|
|
||||||
With no `SUPABASE_URL` set, **authentication is disabled in development** and
|
With no `SUPABASE_URL` set, **authentication is disabled in development** and
|
||||||
@@ -76,7 +83,7 @@ in production without it, so this cannot leak.
|
|||||||
Before pushing:
|
Before pushing:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run typecheck && npm test
|
pnpm run typecheck && pnpm test
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -169,6 +176,21 @@ document.documentElement.scrollWidth - document.documentElement.clientWidth
|
|||||||
|
|
||||||
It should be 0 on every route at 393px wide.
|
It should be 0 on every route at 393px wide.
|
||||||
|
|
||||||
|
**pnpm needs `CI=true` in any non-interactive build.** When it decides a
|
||||||
|
modules directory is stale it asks before removing it; with no TTY it cannot
|
||||||
|
ask, so it aborts with `ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY`. This reads
|
||||||
|
like a pnpm bug and is not — it is pnpm refusing to delete files nobody
|
||||||
|
confirmed. Both the Dockerfile and CI set it. The usual trigger is a host
|
||||||
|
`node_modules` reaching the build context, which is why `.dockerignore` exists:
|
||||||
|
pnpm's tree is symlinks into a content-addressed store, so copying it into an
|
||||||
|
image yields dangling links and a modules directory pnpm considers corrupt.
|
||||||
|
|
||||||
|
**`tsx` is a production dependency, not a dev one.** The server runs TypeScript
|
||||||
|
directly — `pnpm exec tsx apps/api/src/server.ts` is the container's command —
|
||||||
|
so pruning it away breaks the image. It lives in `dependencies` deliberately;
|
||||||
|
moving it back to `devDependencies` because "it's a build tool" makes
|
||||||
|
`pnpm install --prod` produce an image that cannot start.
|
||||||
|
|
||||||
**Drizzle-generated migrations are not always valid SQL.** A `jsonb → integer`
|
**Drizzle-generated migrations are not always valid SQL.** A `jsonb → integer`
|
||||||
cast was emitted without the `USING` clause Postgres requires. Always apply a
|
cast was emitted without the `USING` clause Postgres requires. Always apply a
|
||||||
new migration to a real empty database before pushing — CI does this, but find
|
new migration to a real empty database before pushing — CI does this, but find
|
||||||
|
|||||||
+38
-17
@@ -9,51 +9,72 @@
|
|||||||
FROM node:22-alpine AS build
|
FROM node:22-alpine AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Manifests first, so a dependency install is cached across source-only edits.
|
# Corepack installs the exact pnpm pinned by `packageManager`, so the image
|
||||||
COPY package.json package-lock.json* ./
|
# builds with the same version as CI and as a developer's laptop.
|
||||||
|
#
|
||||||
|
# Both variables are load-bearing in a container build, and neither is
|
||||||
|
# optional:
|
||||||
|
# - the download prompt cannot be answered by a non-interactive build;
|
||||||
|
# - CI=true is what stops pnpm asking for confirmation before it touches a
|
||||||
|
# modules directory it considers stale. Without it the build fails with
|
||||||
|
# ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY, which reads like a bug but is
|
||||||
|
# pnpm correctly refusing to delete files nobody confirmed.
|
||||||
|
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||||
|
ENV CI=true
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
|
# Manifests and the lockfile first, so a dependency install is cached across
|
||||||
|
# source-only edits. pnpm needs every workspace manifest present to resolve the
|
||||||
|
# graph, hence the file-by-file copy rather than `COPY . .`.
|
||||||
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||||
COPY packages/core/package.json packages/core/
|
COPY packages/core/package.json packages/core/
|
||||||
COPY packages/db/package.json packages/db/
|
COPY packages/db/package.json packages/db/
|
||||||
COPY packages/prime/package.json packages/prime/
|
COPY packages/prime/package.json packages/prime/
|
||||||
COPY apps/api/package.json apps/api/
|
COPY apps/api/package.json apps/api/
|
||||||
COPY apps/web/package.json apps/web/
|
COPY apps/web/package.json apps/web/
|
||||||
COPY apps/mcp/package.json apps/mcp/
|
COPY apps/mcp/package.json apps/mcp/
|
||||||
|
COPY apps/cli/package.json apps/cli/
|
||||||
COPY apps/piggy/package.json apps/piggy/
|
COPY apps/piggy/package.json apps/piggy/
|
||||||
RUN npm install --no-audit --no-fund
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Typecheck as a build gate. A deploy that does not compile should fail here,
|
# Typecheck as a build gate. A deploy that does not compile should fail here,
|
||||||
# loudly, rather than at runtime in front of a user.
|
# loudly, rather than at runtime in front of a user.
|
||||||
RUN npx tsc --noEmit -p packages/core/tsconfig.json \
|
RUN pnpm run typecheck
|
||||||
&& npx tsc --noEmit -p packages/db/tsconfig.json \
|
|
||||||
&& npx tsc --noEmit -p packages/prime/tsconfig.json \
|
|
||||||
&& npx tsc --noEmit -p apps/api/tsconfig.json \
|
|
||||||
&& npx tsc --noEmit -p apps/web/tsconfig.json \
|
|
||||||
&& npx tsc --noEmit -p apps/mcp/tsconfig.json \
|
|
||||||
&& npx tsc --noEmit -p apps/piggy/tsconfig.json
|
|
||||||
|
|
||||||
RUN npm run build -w @pig/web
|
RUN pnpm -F @pig/web run build
|
||||||
|
|
||||||
# ---------------------------------------------------------------- runtime
|
# ---------------------------------------------------------------- runtime
|
||||||
FROM node:22-alpine AS runtime
|
FROM node:22-alpine AS runtime
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||||
|
ENV CI=true
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
# Reinstall without dev dependencies. tsx is needed at runtime because the
|
# Install production dependencies only. The server runs TypeScript directly, so
|
||||||
# server runs TypeScript directly; everything else is production-only.
|
# tsx is declared in `dependencies` rather than `devDependencies` — it is
|
||||||
COPY package.json package-lock.json* ./
|
# genuinely needed at runtime, and pretending otherwise meant the old image had
|
||||||
|
# to reinstall it by hand after pruning.
|
||||||
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||||
COPY packages/core/package.json packages/core/
|
COPY packages/core/package.json packages/core/
|
||||||
COPY packages/db/package.json packages/db/
|
COPY packages/db/package.json packages/db/
|
||||||
COPY packages/prime/package.json packages/prime/
|
COPY packages/prime/package.json packages/prime/
|
||||||
COPY apps/api/package.json apps/api/
|
COPY apps/api/package.json apps/api/
|
||||||
COPY apps/mcp/package.json apps/mcp/
|
COPY apps/mcp/package.json apps/mcp/
|
||||||
|
COPY apps/cli/package.json apps/cli/
|
||||||
COPY apps/piggy/package.json apps/piggy/
|
COPY apps/piggy/package.json apps/piggy/
|
||||||
RUN npm install --omit=dev --no-audit --no-fund && npm install tsx --no-audit --no-fund
|
# apps/web is a build-time workspace only; its manifest is still required for
|
||||||
|
# the lockfile to resolve, but none of its dependencies are installed here.
|
||||||
|
COPY apps/web/package.json apps/web/
|
||||||
|
RUN pnpm install --frozen-lockfile --prod --ignore-scripts
|
||||||
|
|
||||||
COPY packages ./packages
|
COPY packages ./packages
|
||||||
COPY apps/api ./apps/api
|
COPY apps/api ./apps/api
|
||||||
COPY apps/mcp ./apps/mcp
|
COPY apps/mcp ./apps/mcp
|
||||||
|
COPY apps/cli ./apps/cli
|
||||||
COPY apps/piggy ./apps/piggy
|
COPY apps/piggy ./apps/piggy
|
||||||
COPY --from=build /app/apps/web/dist ./apps/web/dist
|
COPY --from=build /app/apps/web/dist ./apps/web/dist
|
||||||
|
|
||||||
@@ -63,9 +84,9 @@ USER node
|
|||||||
|
|
||||||
EXPOSE 8920
|
EXPOSE 8920
|
||||||
|
|
||||||
# The health endpoint is unauthenticated by design so this works without
|
# The health endpoint is unauthenticated by design, so this works without
|
||||||
# credentials baked into the image.
|
# credentials baked into the image.
|
||||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
||||||
CMD node -e "fetch('http://127.0.0.1:8920/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
CMD node -e "fetch('http://127.0.0.1:8920/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
||||||
|
|
||||||
CMD ["npx", "tsx", "apps/api/src/server.ts"]
|
CMD ["pnpm", "exec", "tsx", "apps/api/src/server.ts"]
|
||||||
|
|||||||
@@ -125,12 +125,12 @@ application must not grant access here.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <this-repo> pig && cd pig
|
git clone <this-repo> pig && cd pig
|
||||||
npm install
|
pnpm install
|
||||||
cp .env.example .env # then edit it
|
cp .env.example .env # then edit it
|
||||||
npm run db:migrate
|
pnpm run db:migrate
|
||||||
npm run db:seed # optional — public, sourced, confidence-graded
|
pnpm run db:seed # optional — public, sourced, confidence-graded
|
||||||
npm run dev:api # :8920
|
pnpm run dev:api # :8920
|
||||||
npm run dev:web # :5173
|
pnpm run dev:web # :5173
|
||||||
```
|
```
|
||||||
|
|
||||||
Connect an agent:
|
Connect an agent:
|
||||||
|
|||||||
@@ -15,9 +15,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hono/node-server": "^1.13.7",
|
"@hono/node-server": "^1.13.7",
|
||||||
"@noble/curves": "^1.9.7",
|
"@noble/curves": "^1.9.7",
|
||||||
"@pig/core": "*",
|
"@pig/core": "workspace:*",
|
||||||
"@pig/db": "*",
|
"@pig/db": "workspace:*",
|
||||||
"@pig/prime": "*",
|
"@pig/prime": "workspace:*",
|
||||||
"drizzle-orm": "^0.38.3",
|
"drizzle-orm": "^0.38.3",
|
||||||
"hono": "^4.6.14",
|
"hono": "^4.6.14",
|
||||||
"jose": "^5.9.6",
|
"jose": "^5.9.6",
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": { "pig-mcp": "./src/stdio.ts" },
|
"bin": {
|
||||||
|
"pig-mcp": "./src/stdio.ts"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsx src/stdio.ts",
|
"dev": "tsx src/stdio.ts",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pig/core": "*",
|
"@pig/core": "workspace:*",
|
||||||
"@modelcontextprotocol/sdk": "^1.30.0",
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
"test": "node --test --import tsx test/*.test.ts"
|
"test": "node --test --import tsx test/*.test.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pig/core": "*",
|
"@pig/core": "workspace:*",
|
||||||
"@pig/db": "*",
|
"@pig/db": "workspace:*",
|
||||||
"drizzle-orm": "^0.38.3",
|
"drizzle-orm": "^0.38.3",
|
||||||
"zod": "^3.24.1",
|
"zod": "^3.24.1",
|
||||||
"zod-to-json-schema": "^3.25.1"
|
"zod-to-json-schema": "^3.25.1"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^5.7.1",
|
"@hookform/resolvers": "^5.7.1",
|
||||||
"@pig/core": "*",
|
"@pig/core": "workspace:*",
|
||||||
"@radix-ui/react-avatar": "^1.2.6",
|
"@radix-ui/react-avatar": "^1.2.6",
|
||||||
"@radix-ui/react-checkbox": "^1.3.11",
|
"@radix-ui/react-checkbox": "^1.3.11",
|
||||||
"@radix-ui/react-dialog": "^1.1.23",
|
"@radix-ui/react-dialog": "^1.1.23",
|
||||||
|
|||||||
+3
-3
@@ -44,8 +44,8 @@ a query string, where proxies and access logs can retain it.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -p pig up -d --build
|
docker compose -p pig up -d --build
|
||||||
docker compose -p pig exec app npx tsx packages/db/src/migrate.ts
|
docker compose -p pig exec app pnpm exec tsx packages/db/src/migrate.ts
|
||||||
docker compose -p pig exec app npx tsx packages/db/src/seed/index.ts # optional
|
docker compose -p pig exec app pnpm exec tsx packages/db/src/seed/index.ts # optional
|
||||||
```
|
```
|
||||||
|
|
||||||
When Piggy is enabled, start its private profile as well:
|
When Piggy is enabled, start its private profile as well:
|
||||||
@@ -88,7 +88,7 @@ curl -s https://primeintellectgrowth.com/api/health
|
|||||||
```bash
|
```bash
|
||||||
git pull
|
git pull
|
||||||
docker compose -p pig up -d --build
|
docker compose -p pig up -d --build
|
||||||
docker compose -p pig exec app npx tsx packages/db/src/migrate.ts
|
docker compose -p pig exec app pnpm exec tsx packages/db/src/migrate.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
Migrations are additive and safe to re-run; Drizzle tracks what has been
|
Migrations are additive and safe to re-run; Drizzle tracks what has been
|
||||||
|
|||||||
+3
-3
@@ -37,9 +37,9 @@ filesystem command. Configure it separately from the MCP process:
|
|||||||
export PIG_API_URL=https://primeintellectgrowth.com
|
export PIG_API_URL=https://primeintellectgrowth.com
|
||||||
export PIG_API_KEY=pig_...
|
export PIG_API_KEY=pig_...
|
||||||
|
|
||||||
npm run pig -- me
|
pnpm run pig -- me
|
||||||
npm run pig -- --json capacity idle --threshold 0.2
|
pnpm run pig -- --json capacity idle --threshold 0.2
|
||||||
npm run pig -- --json capacity search --gpu-type H100_80GB --min-gpu-count 8
|
pnpm run pig -- --json capacity search --gpu-type H100_80GB --min-gpu-count 8
|
||||||
```
|
```
|
||||||
|
|
||||||
`--api-url` and `--api-key` override the environment for one invocation. In
|
`--api-url` and `--api-key` override the environment for one invocation. In
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ permanently.
|
|||||||
Seeding is a separate command and is never automatic:
|
Seeding is a separate command and is never automatic:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run db:seed # opt in
|
pnpm run db:seed # opt in
|
||||||
```
|
```
|
||||||
|
|
||||||
Skip it and PIG starts empty apart from a development user.
|
Skip it and PIG starts empty apart from a development user.
|
||||||
|
|||||||
Generated
-7502
File diff suppressed because it is too large
Load Diff
+19
-19
@@ -6,32 +6,32 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22"
|
"node": ">=22",
|
||||||
|
"pnpm": ">=11"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
|
||||||
"packages/*",
|
|
||||||
"apps/*"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build --workspaces --if-present",
|
"build": "pnpm -r --if-present run build",
|
||||||
"typecheck": "npm run typecheck --workspaces --if-present",
|
"typecheck": "pnpm -r --if-present run typecheck",
|
||||||
"test": "npm run test --workspaces --if-present",
|
"test": "pnpm -r --if-present run test",
|
||||||
"test:e2e": "npm run test:e2e -w @pig/api",
|
"test:e2e": "pnpm -F @pig/api run test:e2e",
|
||||||
"lint": "npm run lint --workspaces --if-present",
|
"lint": "pnpm -r --if-present run lint",
|
||||||
"dev:api": "npm run dev -w @pig/api",
|
"dev:api": "pnpm -F @pig/api run dev",
|
||||||
"dev:web": "npm run dev -w @pig/web",
|
"dev:web": "pnpm -F @pig/web run dev",
|
||||||
"dev:mcp": "npm run dev -w @pig/mcp",
|
"dev:mcp": "pnpm -F @pig/mcp run dev",
|
||||||
"dev:piggy": "npm run dev -w @pig/piggy",
|
"dev:piggy": "pnpm -F @pig/piggy run dev",
|
||||||
"pig": "tsx apps/cli/src/main.ts",
|
"pig": "tsx apps/cli/src/main.ts",
|
||||||
"db:generate": "npm run generate -w @pig/db",
|
"db:generate": "pnpm -F @pig/db run generate",
|
||||||
"db:migrate": "npm run migrate -w @pig/db",
|
"db:migrate": "pnpm -F @pig/db run migrate",
|
||||||
"db:seed": "npm run seed -w @pig/db",
|
"db:seed": "pnpm -F @pig/db run seed",
|
||||||
"db:demo": "npm run demo -w @pig/db"
|
"db:demo": "pnpm -F @pig/db run demo"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.10.2",
|
||||||
"playwright": "^1.62.1",
|
"playwright": "^1.62.1",
|
||||||
"tsx": "^4.19.2",
|
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@11.21.0",
|
||||||
|
"dependencies": {
|
||||||
|
"tsx": "^4.19.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"demo": "tsx src/seed/demo.ts"
|
"demo": "tsx src/seed/demo.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pig/core": "*",
|
"@pig/core": "workspace:*",
|
||||||
"drizzle-orm": "^0.38.3",
|
"drizzle-orm": "^0.38.3",
|
||||||
"postgres": "^3.4.5"
|
"postgres": "^3.4.5"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,6 @@
|
|||||||
"test": "node --test --import tsx test/*.test.ts"
|
"test": "node --test --import tsx test/*.test.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pig/core": "*"
|
"@pig/core": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+5080
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
|||||||
|
# pnpm workspace definition.
|
||||||
|
#
|
||||||
|
# Replaces npm's `workspaces` field, which has been removed from package.json —
|
||||||
|
# pnpm ignores that field, and keeping both would leave two sources of truth
|
||||||
|
# that can silently disagree.
|
||||||
|
packages:
|
||||||
|
- 'packages/*'
|
||||||
|
- 'apps/*'
|
||||||
|
|
||||||
|
# Dependency install scripts.
|
||||||
|
#
|
||||||
|
# pnpm refuses to run them unless a package is named here, and treats anything
|
||||||
|
# undeclared as a hard error on *every* command until it is resolved. That is a
|
||||||
|
# real supply-chain protection: a transitive dependency cannot execute code at
|
||||||
|
# install time simply by being pulled in.
|
||||||
|
#
|
||||||
|
# `esbuild` asks to run one, and does not need to. Its platform binary arrives
|
||||||
|
# through an optional dependency (`@esbuild/linux-x64`); the postinstall only
|
||||||
|
# verifies what is already present. Checked rather than assumed — after a
|
||||||
|
# scriptless install the binary reported 0.25.12 and both the Vite build and
|
||||||
|
# tsx work normally.
|
||||||
|
#
|
||||||
|
# So it is denied rather than approved: same result, one fewer package allowed
|
||||||
|
# to execute code on every machine that installs. If a build ever genuinely
|
||||||
|
# fails for want of a script, flip it to `true` here and record why.
|
||||||
|
allowBuilds:
|
||||||
|
esbuild: false
|
||||||
+1
-1
@@ -54,7 +54,7 @@ echo "==> Migrating before the schema-dependent app starts"
|
|||||||
# A release may query a newly introduced table during startup. Running the
|
# A release may query a newly introduced table during startup. Running the
|
||||||
# migration from a one-off container prevents that app from crash-looping
|
# migration from a one-off container prevents that app from crash-looping
|
||||||
# before an `exec`-based migration can reach it.
|
# before an `exec`-based migration can reach it.
|
||||||
sudo docker compose -p pig run --rm --no-deps app npx tsx packages/db/src/migrate.ts
|
sudo docker compose -p pig run --rm --no-deps app pnpm exec tsx packages/db/src/migrate.ts
|
||||||
|
|
||||||
echo "==> Starting the app"
|
echo "==> Starting the app"
|
||||||
sudo docker compose -p pig up -d app
|
sudo docker compose -p pig up -d app
|
||||||
|
|||||||
Reference in New Issue
Block a user