update source code (3 files)

This commit is contained in:
-Puter
2026-06-01 18:03:18 +05:30
parent f085783a35
commit 22960be344
13 changed files with 1187 additions and 6160 deletions

View File

@@ -0,0 +1,79 @@
# GrowQR OpenCode runtime image
#
# This wraps the upstream OpenCode image with GrowQR-owned prompt modules,
# sub-agent definitions, workspace template files, and runtime bootstrap.
#
# Build from growqr-backend/:
# docker build -f docker/opencode/Dockerfile -t growqr/opencode:dev .
#
# Release flow:
# docker build -f docker/opencode/Dockerfile \
# --build-arg GROWQR_IMAGE_VERSION=2026.06.01-1 \
# -t ghcr.io/<org>/growqr-opencode:2026.06.01-1 \
# -t ghcr.io/<org>/growqr-opencode:latest .
ARG OPENCODE_BASE_IMAGE=ghcr.io/anomalyco/opencode:latest
FROM ${OPENCODE_BASE_IMAGE}
ARG GROWQR_IMAGE_VERSION=dev
ARG GROWQR_PROMPT_VERSION=dev
ARG GROWQR_MIGRATION_VERSION=1
ENV GROWQR_IMAGE_VERSION=${GROWQR_IMAGE_VERSION}
ENV GROWQR_PROMPT_VERSION=${GROWQR_PROMPT_VERSION}
ENV GROWQR_MIGRATION_VERSION=${GROWQR_MIGRATION_VERSION}
ENV GROWQR_HOME=/opt/growqr
ENV OPENCODE_WORKSPACE=/workspace
USER root
# Ensure the runtime has the basics needed for Git-backed memory. The upstream
# image may already include these, but this keeps our image contract explicit.
RUN if command -v apk >/dev/null 2>&1; then \
apk add --no-cache git openssh-client ca-certificates bash curl jq; \
elif command -v apt-get >/dev/null 2>&1; then \
apt-get update && apt-get install -y --no-install-recommends \
git openssh-client ca-certificates bash curl jq && \
rm -rf /var/lib/apt/lists/*; \
else \
echo "Unsupported base image package manager" >&2; exit 1; \
fi
RUN mkdir -p \
/workspace \
/root/.config/opencode \
/root/.local/share/opencode \
/opt/growqr/agents \
/opt/growqr/prompts \
/opt/growqr/workspace-template/memory \
/opt/growqr/workspace-template/conversations \
/opt/growqr/workspace-template/state \
/opt/growqr/workspace-template/artifacts \
/opt/growqr/workspace-template/workflows \
/opt/growqr/workspace-template/logs \
/opt/growqr/workspace-template/config \
/opt/growqr/workspace-template/metadata
# GrowQR sub-agent prompt modules. These are image-versioned: update the files,
# rebuild/push a new image, then set OPENCODE_IMAGE + OPENCODE_IMAGE_VERSION in
# the backend rollout.
COPY agents/ /opt/growqr/agents/
COPY prompts/ /opt/growqr/prompts/
COPY docker/opencode/growqr.json /root/.config/opencode/growqr.json
COPY docker/opencode/entrypoint.sh /usr/local/bin/growqr-opencode-entrypoint
# Starter Git workspace. The backend will normally create the real central
# Gitea repo and clone it into /workspace after the server starts. This template
# makes fresh/standalone containers still look like a GrowQR memory repo and
# gives OpenCode immediate local context before clone/sync completes.
COPY docker/opencode/workspace-template/ /opt/growqr/workspace-template/
RUN chmod +x /usr/local/bin/growqr-opencode-entrypoint && \
mkdir -p /opt/growqr/workspace-template/metadata && \
printf '%s\n' \
"{\"imageVersion\":\"${GROWQR_IMAGE_VERSION}\",\"promptVersion\":\"${GROWQR_PROMPT_VERSION}\",\"migrationVersion\":\"${GROWQR_MIGRATION_VERSION}\"}" \
> /opt/growqr/workspace-template/metadata/image.json
WORKDIR /workspace
EXPOSE 4096
ENTRYPOINT ["growqr-opencode-entrypoint"]
CMD ["opencode", "serve", "--port", "4096", "--hostname", "0.0.0.0"]

63
docker/opencode/README.md Normal file
View File

@@ -0,0 +1,63 @@
# GrowQR OpenCode Runtime Image
This folder defines the custom per-user OpenCode image used by the Rivet user actor lifecycle.
## Why this exists
The upstream image (`ghcr.io/anomalyco/opencode:latest`) is only the base runtime. GrowQR needs an owned image that bakes in:
- GrowQR sub-agent markdown modules from `agents/`
- GrowQR system prompts from `prompts/`
- global OpenCode config under `/root/.config/opencode`
- a Git-backed workspace template under `/opt/growqr/workspace-template`
- runtime metadata for image/prompt/migration rollout checks
## Local build
From `growqr-backend/`:
```bash
docker build -f docker/opencode/Dockerfile -t growqr/opencode:dev .
```
Then run the backend with:
```bash
OPENCODE_IMAGE=growqr/opencode:dev OPENCODE_IMAGE_VERSION=dev PROMPT_VERSION=dev docker compose up -d --build backend
```
For the current compose setup, the backend talks to the host Docker socket, so local images built on the host are available to per-user containers.
## Release build
```bash
VERSION=2026.06.01-1
docker build -f docker/opencode/Dockerfile \
--build-arg GROWQR_IMAGE_VERSION=$VERSION \
--build-arg GROWQR_PROMPT_VERSION=$VERSION \
-t ghcr.io/<org>/growqr-opencode:$VERSION \
-t ghcr.io/<org>/growqr-opencode:latest .
docker push ghcr.io/<org>/growqr-opencode:$VERSION
docker push ghcr.io/<org>/growqr-opencode:latest
```
Then update backend env:
```bash
OPENCODE_IMAGE=ghcr.io/<org>/growqr-opencode:$VERSION
OPENCODE_IMAGE_VERSION=$VERSION
PROMPT_VERSION=$VERSION
```
## Runtime behavior
The backend/Rivet actor still owns lifecycle:
1. provision central Gitea repo for the user
2. start one OpenCode container from this image
3. mount host workspace at `/workspace`
4. wait for OpenCode readiness
5. clone/pull the user's Gitea repo into `/workspace`
6. sync important runtime outputs back to Git
The image only provides the runtime and templates; user data remains in the user's central Gitea repo.

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env sh
set -eu
WORKSPACE="${OPENCODE_WORKSPACE:-/workspace}"
GROWQR_HOME="${GROWQR_HOME:-/opt/growqr}"
TEMPLATE="$GROWQR_HOME/workspace-template"
mkdir -p "$WORKSPACE" /root/.config/opencode /root/.local/share/opencode
# Make sub-agents discoverable from common OpenCode/global locations. We keep
# the canonical copy in /opt/growqr and symlink/copy to config paths so future
# OpenCode versions can pick up either convention.
ln -sfn "$GROWQR_HOME/agents" /root/.config/opencode/agents
ln -sfn "$GROWQR_HOME/prompts" /root/.config/opencode/prompts
ln -sfn "$GROWQR_HOME/agents" /root/.local/share/opencode/agents
ln -sfn "$GROWQR_HOME/prompts" /root/.local/share/opencode/prompts
# Seed an empty mounted workspace with the GrowQR Git-backed memory shape. The
# backend later clones the user's central Gitea repo over this workspace when it
# provisions the user stack. This only runs for truly empty workspaces.
if [ -z "$(find "$WORKSPACE" -mindepth 1 -maxdepth 1 2>/dev/null | head -n 1)" ]; then
cp -a "$TEMPLATE"/. "$WORKSPACE"/
cat > "$WORKSPACE/README.md" <<EOF
# GrowQR User Workspace
This workspace is controlled by GrowQR's Rivet user actor and backed by the
user's central Gitea repository. OpenCode runs here with GrowQR sub-agents
available globally from:
- /opt/growqr/agents
- /opt/growqr/prompts
- /root/.config/opencode/agents
EOF
git -C "$WORKSPACE" init -b main >/dev/null 2>&1 || true
git -C "$WORKSPACE" config user.email "growqr@local" || true
git -C "$WORKSPACE" config user.name "GrowQR" || true
git -C "$WORKSPACE" add -A >/dev/null 2>&1 || true
git -C "$WORKSPACE" commit -m "init: growqr workspace template" >/dev/null 2>&1 || true
fi
cat > "$WORKSPACE/.growqr-runtime.json" <<EOF
{
"imageVersion": "${GROWQR_IMAGE_VERSION:-dev}",
"promptVersion": "${GROWQR_PROMPT_VERSION:-dev}",
"migrationVersion": "${GROWQR_MIGRATION_VERSION:-1}",
"agentsDir": "$GROWQR_HOME/agents",
"promptsDir": "$GROWQR_HOME/prompts"
}
EOF
exec "$@"

View File

@@ -0,0 +1,10 @@
{
"growqr": {
"name": "GrowQR OpenCode Runtime",
"agentsDir": "/opt/growqr/agents",
"promptsDir": "/opt/growqr/prompts",
"workspace": "/workspace",
"memoryRepo": "git-backed",
"notes": "This file is baked into the custom GrowQR OpenCode image. Update agents/prompts and rebuild the image to release sub-agent changes."
}
}

View File

@@ -0,0 +1,3 @@
# Artifacts
Generated resumes, interview notes, reports, scorecards, and other deliverables.

View File

@@ -0,0 +1,3 @@
# Config
User-specific GrowQR/OpenCode runtime configuration.

View File

@@ -0,0 +1,3 @@
# Conversations
Conversation exports and assistant summaries.

View File

@@ -0,0 +1,3 @@
# Logs
Runtime logs or summaries that are safe to persist to the user's repo.

View File

@@ -0,0 +1,3 @@
# Memory
Durable user career memory. The GrowQR actor and OpenCode runtime should write stable facts, preferences, decisions, and summaries here.

View File

@@ -0,0 +1,3 @@
# State
Small serialized workflow/runtime state that should be visible in Git.

View File

@@ -0,0 +1,3 @@
# Workflows
Workflow run notes, plans, approvals, and outputs.