feat: monorepo consolidation — forge pipeline, MACP protocol, framework plugin, profiles/guides/skills
Work packages completed: - WP1: packages/forge — pipeline runner, stage adapter, board tasks, brief classifier, persona loader with project-level overrides. 89 tests, 95.62% coverage. - WP2: packages/macp — credential resolver, gate runner, event emitter, protocol types. 65 tests, 96.24% coverage. Full Python-to-TS port preserving all behavior. - WP3: plugins/mosaic-framework — OC rails injection plugin (before_agent_start + subagent_spawning hooks for Mosaic contract enforcement). - WP4: profiles/ (domains, tech-stacks, workflows), guides/ (17 docs), skills/ (5 universal skills), forge pipeline assets (48 markdown files). Board deliberation: docs/reviews/consolidation-board-memo.md Brief: briefs/monorepo-consolidation.md Consolidates mosaic/stack (forge, MACP, bootstrap framework) into mosaic/mosaic-stack. 154 new tests total. Zero Python — all TypeScript/ESM.
This commit is contained in:
214
skills/jarvis/SKILL.md
Normal file
214
skills/jarvis/SKILL.md
Normal file
@@ -0,0 +1,214 @@
|
||||
---
|
||||
name: jarvis
|
||||
description: 'Jarvis Platform development context. Use when working on the jetrich/jarvis repository. Provides architecture knowledge, coding patterns, and component locations.'
|
||||
---
|
||||
|
||||
# Jarvis Platform Development
|
||||
|
||||
## Project Overview
|
||||
|
||||
Jarvis is a self-hosted AI assistant platform built with:
|
||||
|
||||
- **Backend:** FastAPI (Python 3.11+)
|
||||
- **Frontend:** Next.js 14+ (App Router)
|
||||
- **Database:** PostgreSQL with pgvector
|
||||
- **Plugins:** Modular LLM providers and integrations
|
||||
|
||||
Repository: `jetrich/jarvis`
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
jarvis/
|
||||
├── apps/
|
||||
│ ├── api/ # FastAPI backend
|
||||
│ │ └── src/
|
||||
│ │ ├── routes/ # API endpoints
|
||||
│ │ ├── services/ # Business logic
|
||||
│ │ ├── models/ # SQLAlchemy models
|
||||
│ │ └── core/ # Config, deps, security
|
||||
│ └── web/ # Next.js frontend
|
||||
│ └── src/
|
||||
│ ├── app/ # App router pages
|
||||
│ ├── components/ # React components
|
||||
│ └── lib/ # Utilities
|
||||
├── packages/
|
||||
│ └── plugins/ # jarvis_plugins package
|
||||
│ └── jarvis_plugins/
|
||||
│ ├── llm/ # LLM providers (ollama, claude, etc.)
|
||||
│ └── integrations/# External integrations
|
||||
├── docs/
|
||||
│ └── scratchpads/ # Agent working docs
|
||||
└── scripts/ # Utility scripts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### LLM Provider Pattern
|
||||
|
||||
All LLM providers implement `BaseLLMProvider`:
|
||||
|
||||
```python
|
||||
# packages/plugins/jarvis_plugins/llm/base.py
|
||||
class BaseLLMProvider(ABC):
|
||||
@abstractmethod
|
||||
async def generate(self, prompt: str, **kwargs) -> str: ...
|
||||
|
||||
@abstractmethod
|
||||
async def stream(self, prompt: str, **kwargs) -> AsyncIterator[str]: ...
|
||||
```
|
||||
|
||||
### Integration Pattern
|
||||
|
||||
External integrations (GitHub, Calendar, etc.) follow:
|
||||
|
||||
```python
|
||||
# packages/plugins/jarvis_plugins/integrations/base.py
|
||||
class BaseIntegration(ABC):
|
||||
@abstractmethod
|
||||
async def authenticate(self, credentials: dict) -> bool: ...
|
||||
|
||||
@abstractmethod
|
||||
async def execute(self, action: str, params: dict) -> dict: ...
|
||||
```
|
||||
|
||||
### API Route Pattern
|
||||
|
||||
FastAPI routes use dependency injection:
|
||||
|
||||
```python
|
||||
@router.get("/items")
|
||||
async def list_items(
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
service: ItemService = Depends(get_item_service)
|
||||
):
|
||||
return await service.list(db, current_user.id)
|
||||
```
|
||||
|
||||
### Frontend Component Pattern
|
||||
|
||||
Use shadcn/ui + server components by default:
|
||||
|
||||
```tsx
|
||||
// Server component (default)
|
||||
export default async function DashboardPage() {
|
||||
const data = await fetchData();
|
||||
return <Dashboard data={data} />;
|
||||
}
|
||||
|
||||
// Client component (when needed)
|
||||
('use client');
|
||||
export function InteractiveWidget() {
|
||||
const [state, setState] = useState();
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Database
|
||||
|
||||
- **ORM:** SQLAlchemy 2.0+
|
||||
- **Migrations:** Alembic
|
||||
- **Vector Store:** pgvector extension
|
||||
|
||||
### Creating Migrations
|
||||
|
||||
```bash
|
||||
cd apps/api
|
||||
alembic revision --autogenerate -m "description"
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Backend
|
||||
|
||||
```bash
|
||||
cd apps/api
|
||||
pytest
|
||||
pytest --cov=src
|
||||
```
|
||||
|
||||
### Frontend
|
||||
|
||||
```bash
|
||||
cd apps/web
|
||||
npm test
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quality Commands
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
cd apps/api
|
||||
ruff check .
|
||||
ruff format .
|
||||
mypy src/
|
||||
|
||||
# Frontend
|
||||
cd apps/web
|
||||
npm run lint
|
||||
npm run typecheck
|
||||
npm run format
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Active Development Areas
|
||||
|
||||
| Issue | Feature | Priority |
|
||||
| ----- | ------------------------------------- | -------- |
|
||||
| #84 | Per-function LLM routing | High |
|
||||
| #85 | Embedded E2E autonomous delivery loop | High |
|
||||
| #86 | Thinking models (CoT UI) | Medium |
|
||||
| #87 | Local image generation | Medium |
|
||||
| #88 | Deep research mode | Medium |
|
||||
| #89 | Uncensored models + alignment | Medium |
|
||||
| #90 | OCR capabilities | Medium |
|
||||
| #91 | Authentik SSO | Medium |
|
||||
| #40 | Claude Max + Claude Code | High |
|
||||
|
||||
---
|
||||
|
||||
## Environment Setup
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
cd apps/api
|
||||
cp .env.example .env
|
||||
pip install -e ".[dev]"
|
||||
|
||||
# Frontend
|
||||
cd apps/web
|
||||
cp .env.example .env.local
|
||||
npm install
|
||||
|
||||
# Database
|
||||
docker-compose up -d postgres
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commit Convention
|
||||
|
||||
```
|
||||
<type>(#issue): Brief description
|
||||
|
||||
Detailed explanation if needed.
|
||||
|
||||
Fixes #123
|
||||
```
|
||||
|
||||
Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore`
|
||||
47
skills/macp/SKILL.md
Normal file
47
skills/macp/SKILL.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
name: macp
|
||||
description: Manage MACP tasks — submit, check status, view history, and drain queues. Use when orchestrating coding tasks via the Mosaic Agent Coordination Protocol.
|
||||
---
|
||||
|
||||
# macp
|
||||
|
||||
MACP task management via the mosaic CLI.
|
||||
|
||||
## Setup
|
||||
|
||||
Ensure PATH includes mosaic bin:
|
||||
|
||||
```bash
|
||||
export PATH="$HOME/.config/mosaic/bin:$PATH"
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Purpose |
|
||||
| ----------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `mosaic macp status` | Show queue counts (pending/running/completed/failed/escalated) |
|
||||
| `mosaic macp submit --task-id ID --title "..." --type coding --command "..."` | Submit a task |
|
||||
| `mosaic macp history --task-id ID` | Show event history for a task |
|
||||
| `mosaic macp drain` | Run all pending tasks sequentially |
|
||||
| `mosaic macp watch --once` | Poll events once |
|
||||
|
||||
## Common Workflows
|
||||
|
||||
**Check what's in the queue:**
|
||||
|
||||
```bash
|
||||
export PATH="$HOME/.config/mosaic/bin:$PATH"
|
||||
mosaic macp status
|
||||
```
|
||||
|
||||
**Submit a coding task:**
|
||||
|
||||
```bash
|
||||
mosaic macp submit --task-id TASK-001 --title "Fix auth bug" --type coding --command "echo done"
|
||||
```
|
||||
|
||||
**View task history:**
|
||||
|
||||
```bash
|
||||
mosaic macp history --task-id TASK-001
|
||||
```
|
||||
32
skills/mosaic-standards/SKILL.md
Normal file
32
skills/mosaic-standards/SKILL.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: mosaic-standards
|
||||
description: Load machine-wide Mosaic standards and enforce the repository lifecycle contract. Use at session start for any coding runtime (Codex, Claude, OpenCode, etc.).
|
||||
---
|
||||
|
||||
# Mosaic Standards
|
||||
|
||||
## Load Order
|
||||
|
||||
1. `~/.config/mosaic/STANDARDS.md`
|
||||
2. Repository `AGENTS.md`
|
||||
3. Repo-local `.mosaic/repo-hooks.sh` when present
|
||||
|
||||
## Session Lifecycle
|
||||
|
||||
- Start: `scripts/agent/session-start.sh`
|
||||
- Priority scan: `scripts/agent/critical.sh`
|
||||
- End: `scripts/agent/session-end.sh`
|
||||
|
||||
If wrappers are available, you may use:
|
||||
|
||||
- `mosaic-session-start`
|
||||
- `mosaic-critical`
|
||||
- `mosaic-session-end`
|
||||
|
||||
## Enforcement Rules
|
||||
|
||||
- Treat `~/.config/mosaic` as canonical for shared guides, tools, profiles, and skills.
|
||||
- Do not edit generated project views directly when the repo defines canonical data sources.
|
||||
- Pull/rebase before edits in shared repositories.
|
||||
- Run project verification commands before claiming completion.
|
||||
- Use non-destructive git workflow unless explicitly instructed otherwise.
|
||||
264
skills/prd/SKILL.md
Normal file
264
skills/prd/SKILL.md
Normal file
@@ -0,0 +1,264 @@
|
||||
---
|
||||
name: prd
|
||||
description: 'Generate a Product Requirements Document (PRD) for a new feature. Use when planning a feature, starting a new project, or when asked to create a PRD. Triggers on: create a prd, write prd for, plan this feature, requirements for, spec out.'
|
||||
---
|
||||
|
||||
# PRD Generator
|
||||
|
||||
Create detailed Product Requirements Documents that are clear, actionable, and suitable for implementation.
|
||||
|
||||
---
|
||||
|
||||
## The Job
|
||||
|
||||
1. Receive a feature description from the user
|
||||
2. Ask 3-5 essential clarifying questions (with lettered options)
|
||||
3. Generate a structured PRD based on answers
|
||||
4. Save to `tasks/prd-[feature-name].md`
|
||||
|
||||
**Important:** Do NOT start implementing. Just create the PRD.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Clarifying Questions
|
||||
|
||||
Ask only critical questions where the initial prompt is ambiguous. Focus on:
|
||||
|
||||
- **Problem/Goal:** What problem does this solve?
|
||||
- **Core Functionality:** What are the key actions?
|
||||
- **Scope/Boundaries:** What should it NOT do?
|
||||
- **Success Criteria:** How do we know it's done?
|
||||
|
||||
### Format Questions Like This:
|
||||
|
||||
```
|
||||
1. What is the primary goal of this feature?
|
||||
A. Improve user onboarding experience
|
||||
B. Increase user retention
|
||||
C. Reduce support burden
|
||||
D. Other: [please specify]
|
||||
|
||||
2. Who is the target user?
|
||||
A. New users only
|
||||
B. Existing users only
|
||||
C. All users
|
||||
D. Admin users only
|
||||
|
||||
3. What is the scope?
|
||||
A. Minimal viable version
|
||||
B. Full-featured implementation
|
||||
C. Just the backend/API
|
||||
D. Just the UI
|
||||
```
|
||||
|
||||
This lets users respond with "1A, 2C, 3B" for quick iteration.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: PRD Structure
|
||||
|
||||
Generate the PRD with these sections:
|
||||
|
||||
### 1. Introduction/Overview
|
||||
|
||||
Brief description of the feature and the problem it solves.
|
||||
|
||||
### 2. Goals
|
||||
|
||||
Specific, measurable objectives (bullet list).
|
||||
|
||||
### 3. User Stories
|
||||
|
||||
Each story needs:
|
||||
|
||||
- **Title:** Short descriptive name
|
||||
- **Description:** "As a [user], I want [feature] so that [benefit]"
|
||||
- **Acceptance Criteria:** Verifiable checklist of what "done" means
|
||||
|
||||
Each story should be small enough to implement in one focused session.
|
||||
|
||||
**Format:**
|
||||
|
||||
```markdown
|
||||
### US-001: [Title]
|
||||
|
||||
**Description:** As a [user], I want [feature] so that [benefit].
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
- [ ] Specific verifiable criterion
|
||||
- [ ] Another criterion
|
||||
- [ ] Typecheck/lint passes
|
||||
- [ ] **[UI stories only]** Verify in browser using dev-browser skill
|
||||
```
|
||||
|
||||
**Important:**
|
||||
|
||||
- Acceptance criteria must be verifiable, not vague. "Works correctly" is bad. "Button shows confirmation dialog before deleting" is good.
|
||||
- **For any story with UI changes:** Always include "Verify in browser using dev-browser skill" as acceptance criteria. This ensures visual verification of frontend work.
|
||||
|
||||
### 4. Functional Requirements
|
||||
|
||||
Numbered list of specific functionalities:
|
||||
|
||||
- "FR-1: The system must allow users to..."
|
||||
- "FR-2: When a user clicks X, the system must..."
|
||||
|
||||
Be explicit and unambiguous.
|
||||
|
||||
### 5. Non-Goals (Out of Scope)
|
||||
|
||||
What this feature will NOT include. Critical for managing scope.
|
||||
|
||||
### 6. Design Considerations (Optional)
|
||||
|
||||
- UI/UX requirements
|
||||
- Link to mockups if available
|
||||
- Relevant existing components to reuse
|
||||
|
||||
### 7. Technical Considerations (Optional)
|
||||
|
||||
- Known constraints or dependencies
|
||||
- Integration points with existing systems
|
||||
- Performance requirements
|
||||
|
||||
### 8. Success Metrics
|
||||
|
||||
How will success be measured?
|
||||
|
||||
- "Reduce time to complete X by 50%"
|
||||
- "Increase conversion rate by 10%"
|
||||
|
||||
### 9. Open Questions
|
||||
|
||||
Remaining questions or areas needing clarification.
|
||||
|
||||
---
|
||||
|
||||
## Writing for Junior Developers
|
||||
|
||||
The PRD reader may be a junior developer or AI agent. Therefore:
|
||||
|
||||
- Be explicit and unambiguous
|
||||
- Avoid jargon or explain it
|
||||
- Provide enough detail to understand purpose and core logic
|
||||
- Number requirements for easy reference
|
||||
- Use concrete examples where helpful
|
||||
|
||||
---
|
||||
|
||||
## Output
|
||||
|
||||
- **Format:** Markdown (`.md`)
|
||||
- **Location:** `tasks/`
|
||||
- **Filename:** `prd-[feature-name].md` (kebab-case)
|
||||
|
||||
---
|
||||
|
||||
## Example PRD
|
||||
|
||||
```markdown
|
||||
# PRD: Task Priority System
|
||||
|
||||
## Introduction
|
||||
|
||||
Add priority levels to tasks so users can focus on what matters most. Tasks can be marked as high, medium, or low priority, with visual indicators and filtering to help users manage their workload effectively.
|
||||
|
||||
## Goals
|
||||
|
||||
- Allow assigning priority (high/medium/low) to any task
|
||||
- Provide clear visual differentiation between priority levels
|
||||
- Enable filtering and sorting by priority
|
||||
- Default new tasks to medium priority
|
||||
|
||||
## User Stories
|
||||
|
||||
### US-001: Add priority field to database
|
||||
|
||||
**Description:** As a developer, I need to store task priority so it persists across sessions.
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
- [ ] Add priority column to tasks table: 'high' | 'medium' | 'low' (default 'medium')
|
||||
- [ ] Generate and run migration successfully
|
||||
- [ ] Typecheck passes
|
||||
|
||||
### US-002: Display priority indicator on task cards
|
||||
|
||||
**Description:** As a user, I want to see task priority at a glance so I know what needs attention first.
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
- [ ] Each task card shows colored priority badge (red=high, yellow=medium, gray=low)
|
||||
- [ ] Priority visible without hovering or clicking
|
||||
- [ ] Typecheck passes
|
||||
- [ ] Verify in browser using dev-browser skill
|
||||
|
||||
### US-003: Add priority selector to task edit
|
||||
|
||||
**Description:** As a user, I want to change a task's priority when editing it.
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
- [ ] Priority dropdown in task edit modal
|
||||
- [ ] Shows current priority as selected
|
||||
- [ ] Saves immediately on selection change
|
||||
- [ ] Typecheck passes
|
||||
- [ ] Verify in browser using dev-browser skill
|
||||
|
||||
### US-004: Filter tasks by priority
|
||||
|
||||
**Description:** As a user, I want to filter the task list to see only high-priority items when I'm focused.
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
- [ ] Filter dropdown with options: All | High | Medium | Low
|
||||
- [ ] Filter persists in URL params
|
||||
- [ ] Empty state message when no tasks match filter
|
||||
- [ ] Typecheck passes
|
||||
- [ ] Verify in browser using dev-browser skill
|
||||
|
||||
## Functional Requirements
|
||||
|
||||
- FR-1: Add `priority` field to tasks table ('high' | 'medium' | 'low', default 'medium')
|
||||
- FR-2: Display colored priority badge on each task card
|
||||
- FR-3: Include priority selector in task edit modal
|
||||
- FR-4: Add priority filter dropdown to task list header
|
||||
- FR-5: Sort by priority within each status column (high to medium to low)
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No priority-based notifications or reminders
|
||||
- No automatic priority assignment based on due date
|
||||
- No priority inheritance for subtasks
|
||||
|
||||
## Technical Considerations
|
||||
|
||||
- Reuse existing badge component with color variants
|
||||
- Filter state managed via URL search params
|
||||
- Priority stored in database, not computed
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- Users can change priority in under 2 clicks
|
||||
- High-priority tasks immediately visible at top of lists
|
||||
- No regression in task list performance
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should priority affect task ordering within a column?
|
||||
- Should we add keyboard shortcuts for priority changes?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Before saving the PRD:
|
||||
|
||||
- [ ] Asked clarifying questions with lettered options
|
||||
- [ ] Incorporated user's answers
|
||||
- [ ] User stories are small and specific
|
||||
- [ ] Functional requirements are numbered and unambiguous
|
||||
- [ ] Non-goals section defines clear boundaries
|
||||
- [ ] Saved to `tasks/prd-[feature-name].md`
|
||||
309
skills/setup-cicd/SKILL.md
Normal file
309
skills/setup-cicd/SKILL.md
Normal file
@@ -0,0 +1,309 @@
|
||||
---
|
||||
name: setup-cicd
|
||||
description: 'Configure CI/CD Docker build, push, and package linking for a project. Use when adding Docker builds to a Woodpecker pipeline, setting up Gitea container registry, or implementing CI/CD for deployment. Triggers on: setup cicd, add docker builds, configure pipeline, add ci/cd, setup ci.'
|
||||
---
|
||||
|
||||
# CI/CD Pipeline Setup
|
||||
|
||||
Configure Docker build, registry push, and package linking for a Woodpecker CI pipeline using Kaniko and Gitea's container registry.
|
||||
|
||||
**Before starting:** Read `~/.config/mosaic/guides/CI-CD-PIPELINES.md` for deep background on the patterns used here.
|
||||
|
||||
**Reference implementation:** `~/src/mosaic-stack/.woodpecker.yml`
|
||||
|
||||
---
|
||||
|
||||
## The Job
|
||||
|
||||
1. Scan the current project for services, Dockerfiles, and registry info
|
||||
2. Ask clarifying questions about what to build and how to name images
|
||||
3. Generate Woodpecker YAML for Docker build/push/link steps
|
||||
4. Provide secrets configuration commands
|
||||
5. Output a verification checklist
|
||||
|
||||
**Important:** This skill generates YAML to _append_ to an existing `.woodpecker.yml`, not replace it. The project should already have quality gate steps (lint, test, typecheck, build).
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Project Scan
|
||||
|
||||
Run these scans and present results to the user:
|
||||
|
||||
### 1a. Detect registry info from git remote
|
||||
|
||||
```bash
|
||||
# Extract Gitea host and org/repo from remote
|
||||
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
|
||||
# Parse: https://git.example.com/org/repo.git -> host=git.example.com, org=org, repo=repo
|
||||
```
|
||||
|
||||
Present:
|
||||
|
||||
- **Registry host:** (extracted from remote)
|
||||
- **Organization:** (extracted from remote)
|
||||
- **Repository:** (extracted from remote)
|
||||
|
||||
### 1b. Find all Dockerfiles
|
||||
|
||||
```bash
|
||||
find . -name "Dockerfile" -o -name "Dockerfile.*" | grep -v node_modules | grep -v .git | sort
|
||||
```
|
||||
|
||||
For each Dockerfile found, note:
|
||||
|
||||
- Path relative to project root
|
||||
- Whether it's a dev variant (`Dockerfile.dev`) or production
|
||||
- The service name (inferred from parent directory)
|
||||
|
||||
### 1c. Detect existing pipeline
|
||||
|
||||
```bash
|
||||
cat .woodpecker.yml 2>/dev/null || cat .woodpecker/*.yml 2>/dev/null
|
||||
```
|
||||
|
||||
Check:
|
||||
|
||||
- Does a `build` step exist? (Docker builds will depend on it)
|
||||
- Are there already Docker build steps? (avoid duplicating)
|
||||
- What's the existing dependency chain?
|
||||
|
||||
### 1d. Find publishable npm packages (if applicable)
|
||||
|
||||
```bash
|
||||
# Find package.json files without "private": true
|
||||
find . -name "package.json" -not -path "*/node_modules/*" -exec grep -L '"private": true' {} \;
|
||||
```
|
||||
|
||||
### 1e. Present scan results
|
||||
|
||||
Show the user a summary table:
|
||||
|
||||
```
|
||||
=== CI/CD Scan Results ===
|
||||
Registry: git.example.com
|
||||
Organization: org-name
|
||||
Repository: repo-name
|
||||
|
||||
Dockerfiles Found:
|
||||
1. src/backend-api/Dockerfile → backend-api
|
||||
2. src/web-portal/Dockerfile → web-portal
|
||||
3. src/ingest-api/Dockerfile → ingest-api
|
||||
4. src/backend-api/Dockerfile.dev → (dev variant, skip)
|
||||
|
||||
Existing Pipeline: .woodpecker.yml
|
||||
- Has build step: yes (build-all)
|
||||
- Has Docker steps: no
|
||||
|
||||
Publishable npm Packages:
|
||||
- @scope/schemas (src/schemas)
|
||||
- @scope/design-system (src/design-system)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Clarifying Questions
|
||||
|
||||
Ask these questions with lettered options (user can respond "1A, 2B, 3C"):
|
||||
|
||||
```
|
||||
1. Which Dockerfiles should be built in CI?
|
||||
(Select all that apply — list found Dockerfiles with letters)
|
||||
A. src/backend-api/Dockerfile (backend-api)
|
||||
B. src/web-portal/Dockerfile (web-portal)
|
||||
C. src/ingest-api/Dockerfile (ingest-api)
|
||||
D. All of the above
|
||||
E. Other: [specify]
|
||||
|
||||
2. Image naming convention?
|
||||
A. {org}/{service} (e.g., usc/uconnect-backend-api) — Recommended
|
||||
B. {org}/{repo}-{service} (e.g., usc/uconnect-backend-api)
|
||||
C. Custom: [specify]
|
||||
|
||||
3. Do any services need build arguments?
|
||||
A. No build args needed
|
||||
B. Yes: [specify service:KEY=VALUE, e.g., web-portal:NEXT_PUBLIC_API_URL=https://api.example.com]
|
||||
|
||||
4. Which branches should trigger Docker builds?
|
||||
A. main and develop (Recommended)
|
||||
B. main only
|
||||
C. Custom: [specify]
|
||||
|
||||
5. Should npm packages be published? (only if publishable packages found)
|
||||
A. Yes, to Gitea npm registry
|
||||
B. Yes, to custom registry: [specify URL]
|
||||
C. No, skip npm publishing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Generate Pipeline YAML
|
||||
|
||||
### 3a. Add kaniko_setup anchor
|
||||
|
||||
If the project's `.woodpecker.yml` doesn't already have a `kaniko_setup` anchor in its `variables:` section, add it:
|
||||
|
||||
```bash
|
||||
~/.config/mosaic/tools/cicd/generate-docker-steps.sh --kaniko-setup-only --registry REGISTRY_HOST
|
||||
```
|
||||
|
||||
This outputs:
|
||||
|
||||
```yaml
|
||||
# Kaniko base command setup
|
||||
- &kaniko_setup |
|
||||
mkdir -p /kaniko/.docker
|
||||
echo "{\"auths\":{\"REGISTRY\":{\"username\":\"$GITEA_USER\",\"password\":\"$GITEA_TOKEN\"}}}" > /kaniko/.docker/config.json
|
||||
```
|
||||
|
||||
Add this to the existing `variables:` block at the top of `.woodpecker.yml`.
|
||||
|
||||
### 3b. Generate Docker build/push/link steps
|
||||
|
||||
Use the generator script with the user's answers:
|
||||
|
||||
```bash
|
||||
~/.config/mosaic/tools/cicd/generate-docker-steps.sh \
|
||||
--registry REGISTRY \
|
||||
--org ORG \
|
||||
--repo REPO \
|
||||
--service "SERVICE_NAME:DOCKERFILE_PATH" \
|
||||
--service "SERVICE_NAME:DOCKERFILE_PATH" \
|
||||
--branches "main,develop" \
|
||||
--depends-on "BUILD_STEP_NAME" \
|
||||
[--build-arg "SERVICE:KEY=VALUE"] \
|
||||
[--npm-package "@scope/pkg:path" --npm-registry "URL"]
|
||||
```
|
||||
|
||||
### 3c. Present generated YAML
|
||||
|
||||
Show the full YAML output to the user and ask for confirmation before appending to `.woodpecker.yml`.
|
||||
|
||||
### 3d. Append to pipeline
|
||||
|
||||
Append the generated YAML to the end of `.woodpecker.yml`. The kaniko_setup anchor goes in the `variables:` section.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Secrets Checklist
|
||||
|
||||
Present the required Woodpecker secrets and commands to configure them:
|
||||
|
||||
```
|
||||
=== Required Woodpecker Secrets ===
|
||||
|
||||
Configure these at: https://WOODPECKER_HOST/repos/ORG/REPO/settings/secrets
|
||||
|
||||
1. gitea_username
|
||||
Value: Your Gitea username or service account
|
||||
Events: push, manual, tag
|
||||
|
||||
2. gitea_token
|
||||
Value: Gitea token with package:write scope
|
||||
Generate at: https://REGISTRY_HOST/user/settings/applications
|
||||
Events: push, manual, tag
|
||||
|
||||
CLI commands:
|
||||
woodpecker secret add ORG/REPO --name gitea_username --value "USERNAME"
|
||||
woodpecker secret add ORG/REPO --name gitea_token --value "TOKEN"
|
||||
```
|
||||
|
||||
If npm publishing was selected, also list:
|
||||
|
||||
```
|
||||
3. npm_token (if using separate npm registry)
|
||||
Value: npm registry auth token
|
||||
Events: push, manual, tag
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Verification Checklist
|
||||
|
||||
Present this checklist for the user to follow after implementation:
|
||||
|
||||
```
|
||||
=== Verification Checklist ===
|
||||
|
||||
□ 1. Secrets configured in Woodpecker UI
|
||||
→ gitea_username and gitea_token set
|
||||
→ Token has package:write scope
|
||||
|
||||
□ 2. Update docker-compose.yml to use registry images
|
||||
→ Change: build: ./src/backend-api
|
||||
→ To: image: REGISTRY/ORG/SERVICE:${IMAGE_TAG:-dev}
|
||||
|
||||
□ 3. Push to develop branch and verify pipeline
|
||||
→ Quality gates pass
|
||||
→ Docker build steps run (only on main/develop)
|
||||
→ Images appear in Gitea Packages
|
||||
|
||||
□ 4. Verify package linking
|
||||
→ Images linked to repository on Gitea Packages tab
|
||||
→ If linking fails (404), link manually via Gitea web UI
|
||||
|
||||
□ 5. Test image pull
|
||||
→ docker login REGISTRY
|
||||
→ docker pull REGISTRY/ORG/SERVICE:dev
|
||||
|
||||
□ 6. Commit the pipeline changes
|
||||
→ git add .woodpecker.yml
|
||||
→ git commit -m "feat: Add Docker build/push/link to CI pipeline"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example Session
|
||||
|
||||
```
|
||||
User: /setup-cicd
|
||||
|
||||
Agent: Let me scan this project...
|
||||
|
||||
=== CI/CD Scan Results ===
|
||||
Registry: git.uscllc.com
|
||||
Organization: usc
|
||||
Repository: uconnect
|
||||
|
||||
Dockerfiles Found:
|
||||
1. src/backend-api/Dockerfile → backend-api
|
||||
2. src/web-portal/Dockerfile → web-portal
|
||||
3. src/ingest-api/Dockerfile → ingest-api
|
||||
4. src/heartbeat-collector/Dockerfile → heartbeat-collector
|
||||
5. src/field-agent/Dockerfile → field-agent
|
||||
6. src/egress-api/Dockerfile → egress-api
|
||||
|
||||
Existing Pipeline: .woodpecker.yml
|
||||
- Has build step: yes (build-all)
|
||||
- Has Docker steps: no
|
||||
|
||||
I have a few questions:
|
||||
|
||||
1. Which Dockerfiles should be built in CI?
|
||||
A. backend-api
|
||||
B. web-portal
|
||||
C. ingest-api
|
||||
...
|
||||
G. All of the above
|
||||
|
||||
User: 1G, 2A, 3A, 4A
|
||||
|
||||
Agent: Generating pipeline YAML...
|
||||
[shows YAML]
|
||||
Shall I append this to .woodpecker.yml?
|
||||
|
||||
User: Yes
|
||||
|
||||
Agent: Done. Here are the secrets you need to configure:
|
||||
[shows secrets checklist]
|
||||
[shows verification checklist]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- The generator script handles `$$` escaping for Woodpecker shell variables automatically
|
||||
- Package linking requires Gitea 1.24.0+ (the API endpoint was added in that version)
|
||||
- If the project has no existing `.woodpecker.yml`, suggest running `init-project.sh` first to set up quality gates
|
||||
- For the kaniko_setup anchor, the registry hostname must not include `https://` — just the bare hostname
|
||||
- Build context defaults to `.` (project root) for Dockerfiles under `apps/`, `src/`, or `packages/`. For other locations (like `docker/postgres/`), the context is the Dockerfile's parent directory.
|
||||
Reference in New Issue
Block a user