Skip to content

Release v0.3.5 – Daily Standup Management & Production Migrations#11

Merged
techbuzzz merged 49 commits into
mainfrom
develop
Jan 28, 2026
Merged

Release v0.3.5 – Daily Standup Management & Production Migrations#11
techbuzzz merged 49 commits into
mainfrom
develop

Conversation

@techbuzzz

Copy link
Copy Markdown
Owner

Release v0.3.5 – Daily Standup Management & Production Migrations

Release Date: January 27, 2026
Target Branch: main
Source Branch: dev
Status: Ready for production deployment


1. Overview

Release v0.3.5 delivers a production-ready Daily Standup Management system for distributed teams and a robust database migration framework to safely evolve the schema over time. The release is designed to be 100% backward compatible with the previous version (v0.3.0), with a strong focus on stability, observability, and maintainability.


2. Highlights

2.1 Daily Standup Management System

New functionality to support daily standups and team coordination:

  • Standup entries with:

    • Did / Doing / Done

    • Blockers

    • Challenges

    • References / links

  • Per-agent, per-day standup records with uniqueness guarantees

  • Agent heartbeat tracking for health/online status

  • RESTful APIs for CRUD operations and querying standups

  • Frontend views for standup creation, editing, and overview

2.2 Production-Grade Migration System

A new migration mechanism to safely evolve the database schema:

  • Transactional migrations (all-or-nothing)

  • Migration tracking table to avoid re-applying the same migration

  • Idempotent, deterministic execution

  • Helper scripts to create and bootstrap migrations

  • Designed to be safe in containerized / concurrent environments


3. Changes Summary

3.1 Backend

Features:

  • Added models and handlers for:

    • daily_standups – stores daily standup data per agent

    • agent_heartbeats – stores heartbeat events/status

  • Added endpoints (examples, may vary by implementation):

    • POST /api/standups – create/update standup (UPSERT)

    • GET /api/standups – list standups with filters (project, agent, date)

    • GET /api/standups/{id} – get single standup

    • PUT /api/standups/{id} – update standup

    • DELETE /api/standups/{id} – delete standup

    • POST /api/heartbeats – record heartbeat

    • GET /api/agents/{id}/heartbeats – list heartbeats for an agent

Migration framework:

  • New schema_migrations table to track executed migrations

  • Migrations executed transactionally on startup

  • Skips already-applied migrations based on version identifiers

3.2 Database Schema

New tables (conceptual schema):

-- Daily standups
CREATE TABLE daily_standups (
    id UUID PRIMARY KEY,
    agent_id UUID NOT NULL,
    project_id UUID NOT NULL,
    standup_date DATE NOT NULL,
    did TEXT,
    doing TEXT,
    done TEXT,
    blockers TEXT,
    challenges TEXT,
    references TEXT,
    created_at TIMESTAMP,
    updated_at TIMESTAMP,
    UNIQUE (agent_id, standup_date)
);

-- Agent heartbeats
CREATE TABLE agent_heartbeats (
    id UUID PRIMARY KEY,
    agent_id UUID NOT NULL,
    heartbeat_time TIMESTAMP NOT NULL,
    status TEXT DEFAULT 'active',
    metadata JSONB,
    created_at TIMESTAMP
);

-- Migration tracking
CREATE TABLE schema_migrations (
    id SERIAL PRIMARY KEY,
    version VARCHAR(255) UNIQUE NOT NULL,
    applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Indexes (recommended):

CREATE INDEX idx_standups_agent_id
    ON daily_standups (agent_id);

CREATE INDEX idx_standups_project_date
    ON daily_standups (project_id, standup_date);

CREATE INDEX idx_heartbeats_agent_id
    ON agent_heartbeats (agent_id);

CREATE INDEX idx_heartbeats_time
    ON agent_heartbeats (heartbeat_time);

4. Frontend

  • New Standups view (dashboard) for:

    • Viewing standups by project/agent/date

    • Navigating through historical standups

  • New Standup modal/form for:

    • Creating and editing standups

    • Writing content using markdown

  • State management/store updated to:

    • Load, cache, and update standup data

    • Handle loading/error states

  • XSS protection for rendered markdown (e.g. DOMPurify or equivalent)


5. Scripts & Tooling

  • New scripts to manage migrations (names may vary; examples):

    • create-migration – scaffold a new migration with auto-incremented version

    • bootstrap-migrations – bootstrap an existing database into the migration system

  • Startup logic:

    • Runs all pending migrations on app start

    • Logs migration versions and timing


6. Quality & Testing

  • Unit tests: All existing tests passing, new tests added for:

    • Standup creation, update, and querying

    • Heartbeat recording and listing

    • Migration application logic

  • Integration tests: Exercise API flows for:

    • Creating standups

    • Listing standups with filters

    • Recording and listing heartbeats

  • Static checks: Linters / analyzers (go vet or equivalents) are clean

  • Performance: Endpoint latencies verified to be within acceptable limits for typical payload sizes


7. Backward Compatibility

  • No breaking changes:

    • Existing endpoints remain unchanged

    • No removals of existing tables/columns

    • New tables and endpoints are additive

  • The migration framework:

    • Only adds schema; does not drop or alter existing required fields in a breaking way

    • Is safe to run on existing databases after bootstrap


8. Deployment Notes

8.1 Prerequisites

  • Database access with permissions to:

    • Create tables

    • Create indexes

    • Insert into migration tracking table

  • Ability to restart application services

8.2 Upgrade Steps (from previous version)

  1. Update code and pull latest main:
git checkout main
git pull origin main
  1. For existing databases:
  • If migration tracking does not exist yet, run the bootstrap script once (if provided in your repo):

    # Example; adjust path/name to your repo
    ./scripts/bootstrap-migrations.sh
  1. Restart services to apply migrations:
docker-compose down
docker-compose up -d

or, if running directly:

systemctl restart <service-name>
# or
./your-binary
  1. Verify health:
  • Call health endpoint (if available), for example:

    curl http://<host>:<port>/health
  1. Verify standups module:
  • Open the UI and ensure the new Standups section is visible

  • Create a test standup and check it persists as expected


9. Security Considerations

  • Input validation added/updated on new endpoints

  • Standup markdown rendering is sanitized to mitigate XSS

  • SQL operations use parameterized queries

  • Important for production:

    • Ensure authentication/authorization is enabled for standup endpoints

    • Serve the application over HTTPS

    • Consider rate limiting and logging/monitoring for the new APIs


10. Known Limitations / Future Work

  • No built-in analytics yet for standups (e.g., trends, metrics per team)

  • Heartbeat data currently provides basic status; richer status/health dashboards can be added later

  • Migrations are focused on schema; data migrations might need additional conventions or tooling in future versions


11. Summary

Release v0.3.5 is a safe, backward-compatible update that introduces:

  • A complete daily standup management flow (backend + frontend)

  • A production-grade migration system for long-term maintainability

  • Additional tests and safeguards to keep the codebase stable

This version is recommended for deployment to main as the baseline for future feature work.

techbuzzz and others added 8 commits January 23, 2026 13:48
* Ensures that the `postgres_data/` directory and its contents are excluded from version control.
* Prevents accidental commits of local PostgreSQL data files.
Remove outdated RELEASE_v0.2.0 documentation and add new RELEASE_v0.3…
feat(TaskCard): display task ID in the TaskCard component
* feat: add daily standup and agent heartbeat models, migrations, and Vue components

- Implemented DailyStandup and AgentHeartbeat models in Go with necessary fields.
- Created SQL migrations for daily_standups and agent_heartbeats tables with indexes.
- Developed StandupModal component for submitting and editing daily standups with form validation.
- Added standupStore for managing standup data, including fetching, creating, updating, and deleting standups.
- Created Standups view to display a list of daily standups with filtering options and modal integration.
- Enhanced UI with loading states, error handling, and markdown rendering for standup details.

* fix(go.mod): remove 'indirect' comments from dependency requirements

* feat(migrations): implement automatic migration system with tracking and bootstrap scripts

* feat: add release notes for v0.3.5 including daily standup management and migration system

* Initial plan

* Initial plan

* Initial plan

* Add application verification report for v0.3.5

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings January 27, 2026 16:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Release v0.3.5 adds a daily standup management feature (UI + API + schema) and introduces a startup-time migration runner with helper scripts, alongside task reassignment and A2A agent-card compatibility updates.

Changes:

  • Added Daily Standups + Agent Heartbeats: new DB tables, Go handlers/models, and Vue UI (view + modal + store) with markdown rendering.
  • Implemented a migration runner on server startup plus PowerShell/SQL bootstrap tooling for existing databases.
  • Added task reassignment (UI + REST endpoint) and updated A2A agent-card parsing/tests for the newer schema.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
web/src/views/Standups.vue New standups dashboard view (filtering, markdown rendering, CRUD actions).
web/src/views/ProjectDetail.vue Adds task reassignment modal wiring and client-side reassignment request.
web/src/stores/standupStore.js New Pinia store for standup CRUD + heartbeat APIs.
web/src/services/api.js Adds API client methods for standups and heartbeats.
web/src/router/index.js Registers the /standups route.
web/src/components/TaskCard.vue Adds reassign action + truncates task description.
web/src/components/StandupModal.vue New modal for creating/editing standups.
web/src/components/ReassignModal.vue New modal for selecting a new assignee for a task.
web/src/App.vue Adds navigation link to the Standups view.
tests/a2a/integration_test.go Updates integration assertions for new agent-card capabilities schema.
tests/a2a/external_agent_test.go Updates real-world/legacy parsing tests and adds extra nil checks.
tests/a2a/agent_card_test.go Updates unit tests for new schema/legacy capabilities handling.
scripts/create-migration.ps1 New helper to scaffold numbered migration SQL files.
scripts/bootstrap-migrations.ps1 New helper to bootstrap existing DBs into the migration system.
migrations/bootstrap_existing_db.sql One-time bootstrap SQL to create/seed schema_migrations.
migrations/003_daily_standups.sql Adds daily_standups and agent_heartbeats tables + indexes.
internal/models/task.go Adds ReassignTaskRequest model for task reassignment endpoint.
internal/models/standup.go Adds standup + heartbeat models and request types.
internal/models/models_test.go Updates model tests to include more assertions/initialization changes.
internal/mcp/handler.go Adds websocket hub to MCP handler + new reassign_task tool and broadcasting.
internal/handlers/tasks.go Adds PUT /tasks/{id}/reassign handler and websocket broadcast.
internal/handlers/standups.go New HTTP handlers for standups + heartbeats.
internal/a2a/models/agent_card.go Updates custom JSON unmarshal logic to handle legacy capabilities formats.
go.mod Promotes several dependencies from indirect to direct requirements.
docs/releases/RELEASE_v0.3.5.md Adds v0.3.5 release notes.
docs/VERIFICATION_REPORT_v0.3.5.md Adds verification report for v0.3.5.
docs/MIGRATION_IMPLEMENTATION.md Documents the migration system implementation.
docs/MIGRATIONS.md Documents migration usage, conventions, and troubleshooting.
docs/DAILY_STANDUP_QUICK_REFERENCE.md Quick reference for standup APIs/UI usage.
docs/DAILY_STANDUP_FEATURE.md Full documentation for the Daily Standup feature.
cmd/server/main.go Wires new handlers/routes and implements directory-based migration runner.
README.md Adds “Database & Migrations” section and usage instructions.
.gitignore Ignores /.vs directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/a2a/models/agent_card.go
Comment thread internal/handlers/standups.go Outdated
Comment thread internal/handlers/standups.go Outdated
Comment thread web/src/components/ReassignModal.vue Outdated
Comment thread web/src/views/Standups.vue
Comment thread cmd/server/main.go
Comment thread cmd/server/main.go
Comment thread web/src/views/ProjectDetail.vue Outdated
Comment thread web/src/views/Standups.vue
Comment thread scripts/bootstrap-migrations.ps1 Outdated
@techbuzzz

Copy link
Copy Markdown
Owner Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #12, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #13, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #14, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #15, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #16, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #17, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #18, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #19, to work on those changes. Once the pull request is ready, I'll request review from you.

@techbuzzz techbuzzz added the enhancement New feature or request label Jan 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 36 out of 45 changed files in this pull request and generated 9 comments.

Files not reviewed (1)
  • web/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)

web/src/views/Standups.vue:360

  • This view still renders standup.references, but the backend now returns reference_links. Update the view (and any related store normalization) to use the new field, or map/alias the API response so existing UI continues to work.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/server/main.go
Comment on lines +255 to +281
// Acquire advisory lock to prevent concurrent migrations
// Use a fixed integer key for migrations lock (hash of "agent-shaker-migrations")
const migrationLockKey = 918273645

// Try to acquire advisory lock (non-blocking)
var lockAcquired bool
err := db.QueryRow("SELECT pg_try_advisory_lock($1)", migrationLockKey).Scan(&lockAcquired)
if err != nil {
return fmt.Errorf("failed to acquire migration lock: %w", err)
}

if !lockAcquired {
log.Println("Another instance is running migrations, waiting...")
// Block until we can acquire the lock
_, err = db.Exec("SELECT pg_advisory_lock($1)", migrationLockKey)
if err != nil {
return fmt.Errorf("failed to wait for migration lock: %w", err)
}
}

// Ensure we release the lock when done
defer func() {
_, err := db.Exec("SELECT pg_advisory_unlock($1)", migrationLockKey)
if err != nil {
log.Printf("Warning: failed to release migration lock: %v", err)
}
}()

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The advisory lock is acquired/released via db.QueryRow/db.Exec on a pooled *sql.DB. Advisory locks are session (connection) scoped, so acquiring on one connection and unlocking on another can leak the lock (or fail to actually serialize migrations). Use a dedicated *sql.Conn (db.Conn(ctx)) or a single transaction/connection to acquire and defer-unlock on the same session, and close the conn when done.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment thread cmd/server/main.go Outdated
Comment thread migrations/003_daily_standups.sql Outdated
Comment on lines 1 to 2
-- Create daily_standups table
CREATE TABLE IF NOT EXISTS daily_standups (

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This migration file starts with a UTF-8 BOM (the invisible character before --). Some tooling/drivers treat this as a non-whitespace character and can break the first statement/comment. Remove the BOM so the first line begins with plain --.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +11 to 36
ID uuid.UUID `json:"id" db:"id"`
AgentID uuid.UUID `json:"agent_id" db:"agent_id"`
ProjectID uuid.UUID `json:"project_id" db:"project_id"`
StandupDate time.Time `json:"standup_date" db:"standup_date"`
Did string `json:"did" db:"did"` // What I did yesterday
Doing string `json:"doing" db:"doing"` // What I'm doing today
Done string `json:"done" db:"done"` // What I plan to complete
Blockers string `json:"blockers" db:"blockers"` // Any blockers
Challenges string `json:"challenges" db:"challenges"` // Current challenges
ReferenceLinks string `json:"reference_links" db:"reference_links"` // Links, docs, etc.
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}

// CreateStandupRequest represents a request to create a daily standup
type CreateStandupRequest struct {
AgentID uuid.UUID `json:"agent_id"`
ProjectID uuid.UUID `json:"project_id"`
StandupDate string `json:"standup_date"` // YYYY-MM-DD format
Did string `json:"did"`
Doing string `json:"doing"`
Done string `json:"done"`
Blockers string `json:"blockers"`
Challenges string `json:"challenges"`
References string `json:"references"`
AgentID uuid.UUID `json:"agent_id"`
ProjectID uuid.UUID `json:"project_id"`
StandupDate string `json:"standup_date"` // YYYY-MM-DD format
Did string `json:"did"`
Doing string `json:"doing"`
Done string `json:"done"`
Blockers string `json:"blockers"`
Challenges string `json:"challenges"`
ReferenceLinks string `json:"reference_links"`
}

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standup JSON field was renamed from references to reference_links. The current frontend (e.g., StandupModal/Standups view) still sends/reads references, so this will break standup create/update and display. To preserve backward compatibility (as stated in the release notes), keep the JSON name as references (while mapping to DB column reference_links) or accept both references and reference_links in request payloads.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines 335 to 354
const formatDate = (dateString) => {
const date = new Date(dateString)
// Treat as date-only value to avoid timezone shifts
if (!dateString) return ''

const dateOnly = dateString.includes('T') ? dateString.split('T')[0] : dateString
const parts = dateOnly.split('-')

if (parts.length !== 3) {
// Fallback to standard parsing if format is unexpected
return new Date(dateString).toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
})
}

const [year, month, day] = parts.map(Number)
const date = new Date(year, month - 1, day) // Use local timezone with specific date parts
return date.toLocaleDateString('en-US', {

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatDate can still throw RangeError: Invalid time value if dateString is in YYYY-MM-DD shape but contains non-numeric parts (Number(...) => NaN) or out-of-range values. Consider validating that year/month/day are finite and within expected ranges before constructing the Date, and fall back to the standard parsing path when invalid.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines 322 to +324
import { useMcpSetup, downloadFile, downloadAllMcpFiles } from '../composables/useMcpSetup'
import api from '../services/api'

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

downloadFile and downloadAllMcpFiles are imported from ../composables/useMcpSetup but the implementation uses the versions returned by useMcpSetup(...) instead (shadowing the imports). This makes the module imports unused and confusing—remove the unused named imports or rename to avoid shadowing.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +724 to +726
case '.mcp':
downloadFile('.mcp.json', config.mcpVSCodeJson, 'application/json')
break

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .mcp download case is using config.mcpVSCodeJson, which will download the VS Code config under the .mcp.json filename. This should use config.mcpVS2026Json so the downloaded content matches the preview/intent for Visual Studio 2026.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment thread docs/VS2026_MCP_SETUP.md
Comment on lines +9 to +54
### 1. **VS 2026 Dedicated Configuration** (`mcpVS2026Json`)
- Full-featured MCP server configuration optimized for Visual Studio 2026
- Includes schema reference for VS 2026 compatibility
- Comprehensive tool definitions and endpoints
- Enhanced security and logging configuration

### 2. **Root Directory `.mcp.json`**
- Auto-generated `.mcp.json` file for project root
- Recognized automatically by Visual Studio 2026
- No manual configuration required after extraction
- Includes full environment context (project, agent, capabilities)

### 3. **Direct Project Integration**
- New `copyMcpFilesToProject()` function writes files directly to project
- No need to manually copy or extract files
- Automatic directory structure creation
- API-based file management

### 4. **Multi-IDE Support**
Generates configuration for:
- **Visual Studio 2026** - `.mcp.json` in project root
- **VS Code** - `.vscode/settings.json` and `.vscode/mcp.json`
- **Command Line** - PowerShell and Bash scripts
- **GitHub Copilot** - `.github/copilot-instructions.md`

## Configuration Files Generated

### `.mcp.json` (Visual Studio 2026 - Root Directory)
```json
{
"$schema": "https://aka.ms/mcp-server-schema",
"version": "1.0.0",
"servers": {
"agent-shaker": {
"type": "http",
"url": "http://localhost:8080?project_id=...&agent_id=...",
"name": "Agent Shaker MCP Server",
"capabilities": ["resources", "tools", "prompts", "context-sharing"],
"tools": [...],
"resources": {...},
"security": {...},
"logging": {...}
}
}
}
```

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs claim mcpVS2026Json generates a full schema-aware config with tools/resources/security/logging, but the current generator in useMcpSetup.js only emits a minimal servers -> { type, url } structure. Please either update the generator to match the documented output or tone down the documentation/examples so they reflect the actual generated JSON.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment thread internal/handlers/standups.go Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #33, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #34, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #35, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #36, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #37, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

@techbuzzz I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 7 commits January 28, 2026 16:22
* Initial plan

* Fix advisory lock to use dedicated connection for session scope

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>
* Initial plan

* Remove UTF-8 BOM from migrations/003_daily_standups.sql

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>
…up models (#35)

* Initial plan

* Fix backward compatibility: change JSON tag from reference_links to references

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>
…36)

* Initial plan

* Add validation for formatDate to prevent RangeError with invalid dates

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

* Improve date validation: add rollover check and error handling

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

* Refactor formatDate: extract fallback parsing to eliminate duplication

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>
* Initial plan

* Remove unused downloadFile and downloadAllMcpFiles imports

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>
* Initial plan

* Fix .mcp download to use VS2026 config instead of VSCode config

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>
* Initial plan

* Update VS2026 docs to match actual minimal config implementation

Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: techbuzzz <6938100+techbuzzz@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 36 out of 45 changed files in this pull request and generated 6 comments.

Files not reviewed (1)
  • web/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +93 to +104
// Change to temp directory for migration discovery
oldWd, _ := os.Getwd()
migrationsDir := filepath.Join(tmpDir, "migrations")
if err := os.Mkdir(migrationsDir, 0755); err != nil {
t.Fatalf("Failed to create migrations dir: %v", err)
}
if err := os.WriteFile(filepath.Join(migrationsDir, "001_test.sql"), []byte(migrationSQL), 0644); err != nil {
t.Fatalf("Failed to create migration in migrations dir: %v", err)
}
defer os.Chdir(oldWd)
os.Chdir(tmpDir)

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test ignores errors from os.Getwd() and os.Chdir(tmpDir). If either fails, the test may behave unpredictably and the deferred Chdir(oldWd) could also misbehave. Please check both errors (and consider using t.Cleanup for restoring the working directory).

Copilot uses AI. Check for mistakes.
Comment on lines +428 to 438
// Build MCP URL with project and agent context
const baseUrl = urlValue.replace('/api', '')
const mcpUrl = `${baseUrl}?project_id=${projectValue.id}&agent_id=${agentValue.id}`

const config = {
"mcpServers": {
"servers": {
"agent-shaker": {
"url": mcpUrl,
"type": "http",
"metadata": {
"name": "Agent Shaker MCP Server",
"version": "1.0.0",
"description": "Multi-agent coordination platform for collaborative development",
"capabilities": [
"resources",
"tools",
"prompts",
"context-sharing"
]
},
"project": {
"id": project.value.id,
"name": project.value.name,
"description": project.value.description || "",
"status": project.value.status,
"type": "multi-agent"
},
"agent": {
"id": agent.value.id,
"name": agent.value.name,
"role": agent.value.role,
"team": agent.value.team || "default",
"status": agent.value.status
}
"url": mcpUrl
}
}

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mcpVSCodeJson / .vscode/mcp.json is generated with a top-level servers key, but parts of the existing documentation in this repo still describe a mcpServers key (e.g. docs/MCP_JSON_CONFIG.md:15, docs/COPILOT_MCP_INTEGRATION.md:278). Please reconcile these formats (update docs and/or generate a backward-compatible structure) to avoid users producing non-working MCP configs.

Copilot uses AI. Check for mistakes.
Comment on lines +429 to 432
// MCP Setup configuration using composable
const mcpApiUrl = computed(() => {
return `${window.location.protocol}//${window.location.host}/api`
return `${window.location.protocol}//${window.location.hostname}:8080`
})

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mcpApiUrl is hard-coded to window.location.hostname:8080, which drops the current port (if any) and ignores the UI’s configurable backend URL (see web/src/services/api.js using localStorage['mcp-server-url']). This will produce incorrect MCP URLs in non-local deployments or when a custom server URL is set. Consider deriving the MCP base from the same configured server URL (or at least use window.location.host/window.location.origin without hard-coding port 8080).

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +67
The implementation now uses PostgreSQL's `INSERT ... ON CONFLICT DO NOTHING RETURNING` pattern to atomically claim migrations:

```go
var claimedVersion string
err = db.QueryRow(
`INSERT INTO schema_migrations (version, applied_at)
VALUES ($1, CURRENT_TIMESTAMP)
ON CONFLICT (version) DO NOTHING
RETURNING version`,
entry.Name(),
).Scan(&claimedVersion)

if err != nil {
// sql.ErrNoRows means ON CONFLICT happened - another instance claimed this
log.Printf("Migration %s already claimed by another instance, skipping", entry.Name())
continue
}

// Only the instance that successfully claimed the migration reaches here
// and executes the DDL
```

### How It Works

1. Each instance attempts to insert a row into `schema_migrations` for the migration
2. The `ON CONFLICT DO NOTHING` clause prevents errors if the row already exists
3. The `RETURNING version` clause returns the version only if the INSERT succeeded
4. If another instance already claimed the migration:
- `ON CONFLICT` prevents the insert
- No rows are returned
- `Scan()` returns `sql.ErrNoRows`
- The instance safely skips this migration
5. Only one instance will successfully claim and execute each migration

### Benefits

- **No race conditions**: The database enforces atomicity
- **No crashes**: Concurrent instances gracefully skip already-claimed migrations
- **Simple**: No need for advisory locks or external coordination
- **Docker-safe**: Works correctly with `docker-compose up --scale app=3`
- **Production-safe**: Multiple pods/containers can start simultaneously

### Trade-offs

- Migrations are no longer wrapped in a single transaction
- The tracking row is inserted *before* executing the DDL
- If a migration fails:
- The tracking row remains (prevents re-attempts)
- Manual intervention is required to fix and continue
- This is intentional: failed migrations should not auto-retry

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The migration concurrency documentation describes an INSERT ... ON CONFLICT DO NOTHING RETURNING “claim then run” approach and explicitly says migrations are not transactional / the row is inserted before DDL, but the current implementation in cmd/server/main.go uses a session-scoped advisory lock and runs each migration inside a DB transaction before inserting into schema_migrations. Please update this doc to match the actual implementation (or update the implementation to match the doc), otherwise operators will be misled about failure modes and recovery steps.

Copilot uses AI. Check for mistakes.
Comment thread docs/VS2026_MCP_SETUP.md
- Auto-generated `.mcp.json` file for project root
- Recognized automatically by Visual Studio 2026
- No manual configuration required after extraction
- Includes full environment context (project, agent, capabilities)

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bullet claims the generated .mcp.json includes “full environment context (project, agent, capabilities)”, but the example (and the current generator) only includes server type + a URL with project_id/agent_id query params. Please reword to match what is actually generated (or extend the generator if capabilities/context are intended to be embedded in the file).

Suggested change
- Includes full environment context (project, agent, capabilities)
- Includes MCP server type and URL with project and agent identifiers; additional capabilities are provided dynamically by the server or can be added if needed

Copilot uses AI. Check for mistakes.
Comment on lines +186 to +211
// POST /api/projects/{projectId}/mcp-files
func CreateMcpFiles(w http.ResponseWriter, r *http.Request) {
projectId := mux.Vars(r)["projectId"]

var req struct {
Files map[string]string `json:"files"`
}

json.NewDecoder(r.Body).Decode(&req)

// Create directories
os.MkdirAll(filepath.Join(projectDir, ".vscode"), 0755)
os.MkdirAll(filepath.Join(projectDir, ".github"), 0755)
os.MkdirAll(filepath.Join(projectDir, "scripts"), 0755)

// Write files
for path, content := range req.Files {
fullPath := filepath.Join(projectDir, path)
ioutil.WriteFile(fullPath, []byte(content), 0644)
}

// Return success
json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"files": keys(req.Files),
})

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sample implementation of the CreateMcpFiles endpoint writes files using a user-controlled path from req.Files directly into filepath.Join(projectDir, path) without any validation or restriction. If this pattern is implemented as shown, an attacker who can call this endpoint could supply values like "../../../../etc/cron.d/malicious" as keys in files, leading to path traversal and arbitrary file writes outside the intended project directory. To avoid this, constrain path to a fixed allowlist of expected filenames (e.g., specific MCP config files), normalize and verify that fullPath remains within projectDir, and reject any input containing .., absolute paths, or unexpected directory separators before writing to disk.

Suggested change
// POST /api/projects/{projectId}/mcp-files
func CreateMcpFiles(w http.ResponseWriter, r *http.Request) {
projectId := mux.Vars(r)["projectId"]
var req struct {
Files map[string]string `json:"files"`
}
json.NewDecoder(r.Body).Decode(&req)
// Create directories
os.MkdirAll(filepath.Join(projectDir, ".vscode"), 0755)
os.MkdirAll(filepath.Join(projectDir, ".github"), 0755)
os.MkdirAll(filepath.Join(projectDir, "scripts"), 0755)
// Write files
for path, content := range req.Files {
fullPath := filepath.Join(projectDir, path)
ioutil.WriteFile(fullPath, []byte(content), 0644)
}
// Return success
json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"files": keys(req.Files),
})
// allowedMcpFiles defines the only files that can be written by this endpoint.
var allowedMcpFiles = map[string]struct{}{
".vscode/mcp.json": {},
".github/workflows/mcp.yml": {},
"scripts/setup-mcp.sh": {},
}
// POST /api/projects/{projectId}/mcp-files
func CreateMcpFiles(w http.ResponseWriter, r *http.Request) {
projectId := mux.Vars(r)["projectId"]
var req struct {
Files map[string]string `json:"files"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid request body", http.StatusBadRequest)
return
}
// Create directories
if err := os.MkdirAll(filepath.Join(projectDir, ".vscode"), 0755); err != nil {
http.Error(w, "failed to create .vscode directory", http.StatusInternalServerError)
return
}
if err := os.MkdirAll(filepath.Join(projectDir, ".github"), 0755); err != nil {
http.Error(w, "failed to create .github directory", http.StatusInternalServerError)
return
}
if err := os.MkdirAll(filepath.Join(projectDir, "scripts"), 0755); err != nil {
http.Error(w, "failed to create scripts directory", http.StatusInternalServerError)
return
}
// Write files (using a fixed allowlist to prevent path traversal)
for path, content := range req.Files {
if _, ok := allowedMcpFiles[path]; !ok {
http.Error(w, "invalid file path", http.StatusBadRequest)
return
}
fullPath := filepath.Join(projectDir, path)
if err := ioutil.WriteFile(fullPath, []byte(content), 0644); err != nil {
http.Error(w, "failed to write file", http.StatusInternalServerError)
return
}
}
// Return success
if err := json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"files": keys(req.Files),
}); err != nil {
http.Error(w, "failed to encode response", http.StatusInternalServerError)
return
}

Copilot uses AI. Check for mistakes.
@techbuzzz techbuzzz merged commit 95b01b4 into main Jan 28, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants