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
28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/backend_task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Backend Task
description: Non-UI logic under backend/ (services, persistence, loaders)
labels: [area:backend, type:feature]
body:
- type: textarea
id: summary
attributes:
label: Summary
description: Describe the service/storage/settings change.
placeholder: e.g., Typed settings service with load/save
validations:
required: true
- type: textarea
id: scope
attributes:
label: Scope
description: Files/modules to change; avoid touching UI.
placeholder: backend/settings/service.py, backend/store/catalog.py
- type: checkboxes
id: dod
attributes:
label: Definition of Done
options:
- label: Black/Ruff clean
- label: Tests added (round-trip, CRUD)
- label: No module side effects
- label: ≤300 LOC changed

28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/cad_core_task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CAD Core Task
description: Geometry kernels, tools, algorithms, and units (cad_core/)
labels: [area:cad_core, type:feature]
body:
- type: textarea
id: summary
attributes:
label: Summary
description: Describe the geometry/algorithm addition.
placeholder: e.g., Point/Vector/LineSegment + transforms
validations:
required: true
- type: textarea
id: scope
attributes:
label: Scope
description: Modules/functions to add/edit; pure code only.
placeholder: cad_core/geom/primitives.py, cad_core/geom/transform.py
- type: checkboxes
id: dod
attributes:
label: Definition of Done
options:
- label: Black/Ruff clean
- label: Unit tests cover new functions
- label: No UI imports or side effects
- label: ≤300 LOC changed

5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Sprint Plan
url: https://github.com/Obayne/AutoFireBase/blob/main/docs/SPRINT-01.md
about: Review the sprint plan for goals, tasks, and acceptance.
28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/frontend_task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Frontend Task
description: UI work under frontend/ (Qt widgets, views, input)
labels: [area:frontend, type:feature]
body:
- type: textarea
id: summary
attributes:
label: Summary
description: Briefly describe the UI change.
placeholder: e.g., Model Space shell with space selector and lock
validations:
required: true
- type: textarea
id: scope
attributes:
label: Scope
description: Files/components to touch; avoid unrelated edits.
placeholder: frontend/widgets/ModelSpace.py, frontend/menus/ViewMenu.py
- type: checkboxes
id: dod
attributes:
label: Definition of Done
options:
- label: Black/Ruff clean
- label: Tests added/updated (signals, handlers)
- label: No side effects in imports
- label: ≤300 LOC changed

28 changes: 28 additions & 0 deletions .github/seed_issues.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[
{
"title": "Sprint 01: CAD Core — primitives + transforms",
"labels": ["area:cad_core", "type:feature", "sprint:01"],
"body": "Implement Point, Vector, LineSegment and pure transform functions (translate/scale/rotate). Add unit tests with deterministic outputs. See docs/SPRINT-01.md (cad_core section). DoD: Black/Ruff clean; no UI deps; tests added."
},
{
"title": "Sprint 01: Backend — settings service",
"labels": ["area:backend", "type:feature", "sprint:01"],
"body": "Typed settings object with load/save to disk and sensible defaults. Round-trip tests to ensure persistence. See docs/SPRINT-01.md (Backend / Settings service). DoD: Black/Ruff clean; tests; no module side-effects."
},
{
"title": "Sprint 01: Backend — catalog store (SQLite)",
"labels": ["area:backend", "type:feature", "sprint:01"],
"body": "Wrap SQLite access for seed/types/devices/specs with simple CRUD and list/search. Use in-memory fixtures for tests. See docs/SPRINT-01.md (Backend / Catalog store). DoD: Black/Ruff clean; CRUD covered by tests."
},
{
"title": "Sprint 01: Frontend — Model Space shell + command bar",
"labels": ["area:frontend", "type:feature", "sprint:01"],
"body": "Minimal Model Space widget shell. Hide Sheets dock by default with a View menu toggle. Space selector + lock (non-functional toggle wired to backend stub). Command bar emits signal on Enter. See docs/SPRINT-01.md (Frontend / Model Space). DoD: Black/Ruff; signals tested; no crashes."
},
{
"title": "Sprint 01: Frontend — Input handling foundation",
"labels": ["area:frontend", "type:feature", "sprint:01"],
"body": "Centralize key/mouse events in a small handler class and log via signal. Unit test for key mapping. See docs/SPRINT-01.md (Frontend / Input handling). DoD: Black/Ruff; tests; no side-effects."
}
]

65 changes: 65 additions & 0 deletions .github/workflows/agent-orchestrator.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Agent Orchestrator

on:
workflow_dispatch:
issues:
types: [labeled]

jobs:
scaffold:
if: github.event_name == 'workflow_dispatch' || contains(github.event.label.name, 'agent:auto')
runs-on: ubuntu-latest
permissions:
contents: write
issues: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Run orchestrator
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_ACTOR: ${{ github.actor }}
run: |
python tools/agents/orchestrator.py "$GITHUB_EVENT_PATH"

- name: Open PR for new branch (if any)
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const cp = require('child_process');
// Attempt to detect the most recent branch created by this run
const out = cp.execSync('git branch --show-current').toString().trim();
const head = out && out !== '' ? out : null;
if (!head || head === 'main' || head.startsWith('chore/')) {
core.info('No feature branch detected for PR.');
return;
}
const owner = context.repo.owner;
const repo = context.repo.repo;
const base = 'main';
const title = `feat: ${head} (agent scaffold)`;
const body = [
'Automated scaffold for this issue by Agent Orchestrator.',
'',
'Includes minimal stub files and skipped tests to keep CI green.',
'Please replace stubs with real implementations and enable tests.',
].join('\n');
// Check if a PR from this head already exists
const prs = await github.paginate(github.rest.pulls.list, { owner, repo, state: 'open', head: `${owner}:${head}` });
if (prs.length === 0) {
await github.rest.pulls.create({ owner, repo, head, base, title, body });
} else {
core.info(`PR already open: #${prs[0].number}`);
}

75 changes: 75 additions & 0 deletions .github/workflows/assign-owners.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Assign Owners

on:
workflow_dispatch:
issues:
types: [opened, labeled]
pull_request:
types: [opened, labeled, reopened]

jobs:
assign:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
env:
AREA_FRONTEND_OWNER: ${{ vars.AREA_FRONTEND_OWNER }}
AREA_BACKEND_OWNER: ${{ vars.AREA_BACKEND_OWNER }}
AREA_CAD_CORE_OWNER: ${{ vars.AREA_CAD_CORE_OWNER }}
DEFAULT_PR_OWNER: ${{ vars.DEFAULT_PR_OWNER }}
steps:
- name: Assign new/updated issues
if: github.event_name == 'issues'
uses: actions/github-script@v7
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue = context.payload.issue;
const labels = (issue.labels || []).map(l => l.name);
function pickAssignee(labels){
if (labels.includes('area:frontend')) return process.env.AREA_FRONTEND_OWNER || owner;
if (labels.includes('area:backend')) return process.env.AREA_BACKEND_OWNER || owner;
if (labels.includes('area:cad_core')) return process.env.AREA_CAD_CORE_OWNER || owner;
return owner;
}
const login = pickAssignee(labels);
core.info(`Assigning @${login} to issue #${issue.number}`);
await github.rest.issues.addAssignees({ owner, repo, issue_number: issue.number, assignees: [login] });

- name: Batch-assign Sprint 01 issues (manual run)
if: github.event_name == 'workflow_dispatch'
uses: actions/github-script@v7
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issues = await github.paginate(github.rest.issues.listForRepo, { owner, repo, state: 'open', per_page: 100, labels: 'sprint:01' });
for (const i of issues) {
if ((i.assignees || []).length) { continue; }
const labels = (i.labels || []).map(l => l.name);
function pickAssignee(labels){
if (labels.includes('area:frontend')) return process.env.AREA_FRONTEND_OWNER || owner;
if (labels.includes('area:backend')) return process.env.AREA_BACKEND_OWNER || owner;
if (labels.includes('area:cad_core')) return process.env.AREA_CAD_CORE_OWNER || owner;
return owner;
}
const login = pickAssignee(labels);
core.info(`Assigning @${login} to issue #${i.number}`);
await github.rest.issues.addAssignees({ owner, repo, issue_number: i.number, assignees: [login] });
}

- name: Assign PRs
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const pr = context.payload.pull_request;
const login = process.env.DEFAULT_PR_OWNER || owner;
core.info(`Assigning @${login} to PR #${pr.number}`);
await github.rest.issues.addAssignees({ owner, repo, issue_number: pr.number, assignees: [login] });

34 changes: 34 additions & 0 deletions .github/workflows/label-sprint-issues.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Label Sprint Issues for Agents

on:
workflow_dispatch:
push:
branches:
- chore/dev-setup-warnings
paths:
- .github/workflows/label-sprint-issues.yml

jobs:
label:
runs-on: ubuntu-latest
permissions:
issues: write
contents: read
steps:
- name: Add agent:auto label to Sprint 01 issues
uses: actions/github-script@v7
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issues = await github.paginate(github.rest.issues.listForRepo, {
owner, repo, state: 'open', per_page: 100, labels: 'sprint:01'
});
for (const i of issues) {
const has = (i.labels || []).some(l => l.name === 'agent:auto');
if (!has) {
core.info(`Labeling issue #${i.number}: ${i.title}`);
await github.rest.issues.addLabels({ owner, repo, issue_number: i.number, labels: ['agent:auto'] });
}
}

56 changes: 56 additions & 0 deletions .github/workflows/open-pr-chore-dev-setup-warnings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Open PR for chore/dev-setup-warnings

on:
workflow_dispatch:
push:
branches:
- chore/dev-setup-warnings

jobs:
open-pr:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Create or update PR
uses: actions/github-script@v7
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const head = 'chore/dev-setup-warnings';
const base = 'main';

// Check if PR already exists
const prs = await github.paginate(github.rest.pulls.list, { owner, repo, state: 'open', head: `${owner}:${head}` });
if (prs.length > 0) {
core.info(`PR already open: #${prs[0].number}`);
core.setOutput('pr_number', prs[0].number);
return;
}

const title = 'chore: dev setup warnings + Sprint 01 plan + issue templates';
const body = [
'This PR keeps main green and unblocks the team by:',
'',
'- Normalizing dev setup warnings punctuation in `setup_dev.ps1`',
'- Adding Sprint 01 plan at `docs/SPRINT-01.md`',
'- Adding issue templates under `.github/ISSUE_TEMPLATE/`',
'- Adding workflows to seed Sprint issues and auto-open this PR',
'',
'Review focus:',
'- Repo hygiene only; no runtime logic changed beyond script messages',
'- Validate sprint plan structure and labels/templates',
'',
'Links:',
'- Sprint Plan: docs/SPRINT-01.md'
].join('\n');

const pr = await github.rest.pulls.create({ owner, repo, title, head, base, body, draft: false });
core.info(`Opened PR #${pr.data.number}`);
core.setOutput('pr_number', pr.data.number);

Loading
Loading