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
43 changes: 4 additions & 39 deletions .github/agents/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,10 @@
# ordrctrl Development Guidelines

Auto-generated from all feature plans. Last updated: 2026-03-04
Auto-generated from all feature plans. Last updated: 2026-03-22

## Active Technologies
- TypeScript 5.4 (backend: Node.js/Fastify; frontend: React/Next.js 14) + Fastify (backend API), React + Tailwind CSS (frontend), Prisma ORM (002-uncheck-completed)
- PostgreSQL 16 (primary data), Redis 7 (session cache, BullMQ job queue) (002-uncheck-completed)
- TypeScript 5.4 (backend + frontend) + Fastify 4, Prisma 5, BullMQ (backend); Next.js 14 + React 18 + Tailwind CSS (frontend); Zod (validation); Vitest + Supertest (tests) (003-selective-import)
- PostgreSQL 16 (Prisma ORM) — two new columns on `Integration` table; Redis 7 for BullMQ sync queue (003-selective-import)
- TypeScript 5.x / Node.js 20 LTS (backend); React 18 + TypeScript (frontend) + Fastify (HTTP server), Prisma (ORM + migrations), BullMQ (sync queue), node-fetch (CalDAV HTTP), zod (input validation), AES-256-GCM via `backend/src/lib/encryption.ts` (004-apple-basic-auth)
- PostgreSQL via Prisma — one new field (`calendarEventWindowDays Int @default(30)`) on existing `Integration` model; one migration required (004-apple-basic-auth)
- TypeScript (Node.js backend, React frontend) + Fastify (API), Prisma (ORM), Zod (validation), React Query (frontend state) (005-feed-dismissal)
- TypeScript — backend Node.js, frontend Next.js 14 / React 18 + Prisma ORM, BullMQ, existing IntegrationAdapter interface (007-source-sync)
- PostgreSQL via Prisma — one schema migration required (new field + enum) (007-source-sync)
- TypeScript (Node.js 18, Next.js 14) + Prisma ORM, Express-style API routes (Next.js App Router + custom backend), React 18, BullMQ (sync scheduler) (008-clear-completed)
- TypeScript (Node.js 20, Next.js 14) + Fastify (backend), Next.js + React 18 (frontend), Prisma ORM, BullMQ (sync queue), Vitest (tests) (009-multi-account)
- PostgreSQL (via Prisma) (009-multi-account)
- TypeScript 5 (backend Node.js 20, frontend Next.js 14) + Fastify 4, Prisma 5, React 18, Tailwind CSS, BullMQ, Redis (010-task-inbox)
- PostgreSQL (via Prisma ORM) (010-task-inbox)
- TypeScript 5 (backend Node.js 20, frontend Next.js 14.1.3) + Fastify 4, Prisma 5, React 18, Tailwind CSS, BullMQ, Redis (011-feed-ux-enhancements)
- TypeScript 5.x (frontend + backend) + Next.js 14 App Router, React, Express, Prisma, BullMQ, Redis (012-app-polish-bugfix)
- PostgreSQL (via Prisma), Redis (sync-status cache) (012-app-polish-bugfix)
- TypeScript 5.x (backend Node 20 LTS + frontend Next.js 15 App Router) + Fastify (backend API), React 19, Prisma 5 ORM, PostgreSQL 16, Redis (013-task-content-enhancements)
- PostgreSQL via Prisma (primary), Redis (short-lived sync cache metadata) (013-task-content-enhancements)
- TypeScript 5.4.2 / React 18.2.0 / Node.js 18+ + Vite 5.1.4 (already installed), react-router-dom v6 (to add), Tailwind CSS 3.4.1 (014-vite-migration)
- N/A — frontend only; all persistence is in the backend (014-vite-migration)
- TypeScript 5.4 (frontend), Rust 1.75+ (Tauri shell), Swift/Kotlin (Capacitor native bridge — generated) (015-native-app-targets)
- No new storage layer — session cookies persisted by native WebView OS cookie jar; `@capacitor/preferences` for lightweight native-only flags (e.g., last-seen notification timestamp) (015-native-app-targets)
- Redis (existing) — new `oauth:state:{value}` key namespace with 5-min TTL (016-native-auth-fixes)
- TypeScript 5.4 (frontend + backend), Rust 1.75+ (Tauri shell — unaffected) + Fastify 4, Prisma ORM, React 18, Vite 5, Vitest — all existing; no new dependencies (017-task-rename-polish)
- PostgreSQL (existing `SyncOverride` table — adding one new enum value); no schema migrations beyond enum update (017-task-rename-polish)
- TypeScript 5.4 (frontend), Node 20 (CI runners) (018-e2e-testing)
- N/A (tests are read-only; no test data written to persistent storage) (018-e2e-testing)
- TypeScript 5.4 / React 18.2 + React Router DOM v6, Capacitor 8 (iOS/Android), Tauri 2 (macOS/Windows), Vite, Vitest, Playwright (019-task-timeline-view)
- No new storage — `FeedItem[]` from existing `useFeed` hook; view preference via existing `NativePrefs` pattern (`@capacitor/preferences` → `localStorage` fallback) (019-task-timeline-view)
- New `frontend/src/utils/dateUtils.ts`: shared timezone-safe date helpers — `isAllDayDate`, `toLocalMidnight`, `formatRelativeDay`, `formatLocalTime`, `toLocalDateTimeInput`, `toLocalDateInput`; imported by `useTimeline`, `FeedItemRow`, `EditTaskModal` (019-task-timeline-view)
- All-day calendar events use UTC noon sentinel (`T12:00:00.000Z`). Use `isAllDayDate()` to detect; use `toLocalMidnight()` for bucket/day comparison — do NOT call `setHours(0,0,0,0)` directly on dates from external sources. For display, use `formatLocalTime()` (returns `""` for all-day) and `toLocalDateInput()` / `toLocalDateTimeInput()` for form inputs (019-task-timeline-view)
- Apple Calendar events may have `dueAt: null`; always use `dueAt ?? startAt` as the date key for bucketing and display (019-task-timeline-view)

- TypeScript 5.x (frontend + backend) + Next.js 14 (frontend), Fastify 4 (backend API), Prisma (ORM), (001-mvp-core)
- Node.js (TypeScript) — pnpm monorepo; hook scripts in Bash + Copilot CLI agent/skill/hook system; GitHub MCP; `gh` CLI fallback; `jq` (Bash hooks); `git` (020-speckit-workflow)

## Project Structure

Expand All @@ -52,13 +19,11 @@ npm test && npm run lint

## Code Style

TypeScript 5.x (frontend + backend): Follow standard conventions
Node.js (TypeScript) — pnpm monorepo; hook scripts in Bash: Follow standard conventions

## Recent Changes
- 019-task-timeline-view: Added timeline view components, useTimeline hook, dateUtils.ts (toLocalMidnight/isAllDayDate/formatLocalTime), Apple Calendar dueAt fix, UTC-midnight all-day display fixes
- 018-e2e-testing: Added TypeScript 5.4 (frontend), Node 20 (CI runners)
- 017-task-rename-polish: Added TypeScript 5.4 (frontend + backend), Rust 1.75+ (Tauri shell — unaffected) + Fastify 4, Prisma ORM, React 18, Vite 5, Vitest — all existing; no new dependencies

- 020-speckit-workflow: Added Node.js (TypeScript) — pnpm monorepo; hook scripts in Bash + Copilot CLI agent/skill/hook system; GitHub MCP; `gh` CLI fallback; `jq` (Bash hooks); `git`

<!-- MANUAL ADDITIONS START -->
<!-- MANUAL ADDITIONS END -->
171 changes: 171 additions & 0 deletions .github/agents/issue-triage.agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
description: Analyze all open GitHub issues for a repository, group related issues by theme, and produce a prioritized triage report with actionable recommendations.
tools: ['github/github-mcp-server/list_issues', 'github/github-mcp-server/issue_read', 'github/github-mcp-server/search_issues']
---

## User Input

```text
$ARGUMENTS
```

You **MUST** consider the user input before proceeding. The user may specify:
- A specific repository (`owner/repo`) — if not provided, detect from `git config --get remote.origin.url`
- A focus area or label filter to narrow scope
- A maximum number of issues to analyze (default: all open issues, up to 200)

## Goal

Fetch all open issues for the target repository, semantically cluster them into related groups, score each issue for priority, and produce a compact triage report the team can act on immediately.

## Operating Constraints

**READ-ONLY**: Do **not** create, edit, close, or label any issues. Output a structured report only.

**Repository Safety**: Confirm the target repository before fetching. If the user did not specify a repo, derive it from the Git remote and display it before proceeding.

## Execution Steps

### 1. Resolve Target Repository

If the user provided `owner/repo`, use it directly. Otherwise, run:

```bash
git config --get remote.origin.url
```

Parse the output to extract `owner` and `repo`. Display: `Analyzing issues for: owner/repo` before proceeding.

> [!CAUTION]
> Never fetch or create issues in a repository that does not match the user's intent. Confirm with the user if ambiguous.

### 2. Fetch Open Issues

Use the GitHub MCP `list_issues` tool with `state: OPEN`. Page through results until all open issues are collected (respect the 200-issue cap unless the user overrides). For each issue capture:

- Issue number, title, body (first 300 chars), labels, assignees, created_at, updated_at, comment count, reactions count

If the user specified a label filter, apply it during the fetch.

### 3. Build Semantic Clusters

Group issues by **theme** using the following signals (in priority order):

1. **Explicit labels** — issues sharing the same label are strong candidates for the same cluster
2. **Title keyword overlap** — extract noun phrases; issues sharing 2+ key terms belong together
3. **Body reference overlap** — issues mentioning the same file paths, component names, API endpoints, or error messages
4. **Cross-references** — issues that link to each other (`#NNN` mentions) are in the same cluster

Produce clusters with:
- A short **cluster name** (3–5 words, title case)
- A one-sentence **theme description**
- The list of issue numbers belonging to the cluster
- A `SINGLETON` marker for issues that don't cluster with anything

Limit clusters to a maximum of 15 (merge the smallest clusters into an `Other` bucket if needed).

### 4. Score Each Issue for Priority

Assign a **priority score** (1–10, higher = more urgent) using this weighted rubric:

| Signal | Weight | Notes |
|--------|--------|-------|
| Age (days open) | 20% | >90 days = max signal |
| Reaction count (👍, ❤️, 🚀) | 25% | Proxy for user demand |
| Comment count | 15% | High engagement = high interest |
| Recency of last update | 15% | Recently touched = in-flight work |
| Label severity | 25% | `bug` > `enhancement` > `question`; `critical`/`P0` labels = max |

Round score to one decimal. Break ties by reaction count.

Within each cluster, rank issues by score descending.

### 5. Identify Cross-Cutting Concerns

After clustering, scan for these patterns and call them out explicitly:

- **Blocking relationships**: Issues where one references another as a dependency or blocker
- **Duplicates**: Issues with near-identical titles or bodies (>80% semantic overlap) — flag as `POSSIBLE DUPLICATE of #NNN`
- **Stale issues**: Open >180 days with 0 comments and 0 reactions — flag as `STALE`
- **Needs triage**: Issues with no labels assigned

### 6. Produce the Triage Report

Output a Markdown report with the following structure:

---

## Issue Triage Report — `owner/repo`

**Generated**: [timestamp]
**Open Issues Analyzed**: N
**Clusters Identified**: N

---

### Priority Queue (Top 10 Issues Across All Clusters)

| Rank | # | Title | Cluster | Score | Age | 👍 | Labels |
|------|---|-------|---------|-------|-----|----|--------|

---

### Clusters

For each cluster (sorted by highest issue score descending):

#### [Cluster Name]
> [Theme description]

| # | Title | Score | Age | 👍 | Labels | Assignee |
|---|-------|-------|-----|----|--------|----------|

---

### Cross-Cutting Concerns

**Blocking Chains** (if any):
- #NNN → #NNN → #NNN

**Possible Duplicates** (if any):
- #NNN may duplicate #NNN — [reason]

**Stale Issues** (if any):
- #NNN — [title] (open NNN days, 0 activity)

**Needs Triage** (no labels):
- #NNN — [title]

---

### Metrics Summary

| Metric | Value |
|--------|-------|
| Total open issues | N |
| Clusters | N |
| Singletons | N |
| Possible duplicates | N |
| Stale (>180d, no activity) | N |
| Needs triage (no labels) | N |
| Avg issue age (days) | N |

---

### Recommended Next Actions

Based on the analysis, suggest 3–5 concrete, prioritized actions such as:
- "Close or merge duplicates #NNN and #NNN"
- "Add labels to N unlabeled issues before next sprint planning"
- "Cluster `[name]` has N high-priority bugs — consider a dedicated bug bash"
- "Issues #NNN and #NNN should be linked as a blocking dependency"

---

## Operating Principles

- **Never modify issues** — this is a read-only analysis
- **Cite evidence** for every grouping decision (e.g., "shares label `auth`, mentions `session.ts`")
- **Prefer signal over volume** — a short, accurate report beats an exhaustive one
- **Graceful degradation** — if the repo has <5 open issues, skip clustering and just produce a prioritized list
- **Transparency** — if pagination was cut off at the 200-issue cap, note how many were not analyzed
66 changes: 63 additions & 3 deletions .github/agents/speckit.analyze.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@ Identify inconsistencies, duplications, ambiguities, and underspecified items ac

## Execution Steps

### 1. Initialize Analysis Context
### 1. Context Loading (run at startup before any output)

1. Read `.specify/memory/constitution.md`
2. Read `.specify/memory/stack.md` — if absent, warn: "⚠️ stack.md missing — stack-specific command validation will be skipped"
3. If stack.md is present, extract `regression_tests` section to use for command validation:
- `lint_cmd`, `test_cmd`, `e2e_cmd` — verify these exact commands appear in tasks.md regression steps
- If tasks.md uses different (hardcoded) commands, flag as a finding in the analysis report
4. Read current spec's `spec.md`, `plan.md`, `tasks.md`
5. Output one-line summary: `Loaded: [spec name] | Status: [status] | Stack: [packaging tool]`

### 2. Initialize Analysis Context

Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths:

Expand Down Expand Up @@ -158,10 +168,60 @@ At end of report, output a concise Next Actions block:
- If only LOW/MEDIUM: User may proceed, but provide improvement suggestions
- Provide explicit command suggestions: e.g., "Run /speckit.specify with refinement", "Run /speckit.plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'"

### 8. Offer Remediation
### 8. Drift Detection

Before advancing spec status, detect whether the implementation diverged from the original plan:

1. **Find branch-creation commit** (approximate base):
```bash
BASE_COMMIT=$(git log --oneline --reverse HEAD | head -1 | cut -d' ' -f1)
```

2. **Compare spec artifacts against base**:
```bash
BRANCH=$(git rev-parse --abbrev-ref HEAD)
git diff $BASE_COMMIT..HEAD -- specs/$BRANCH/spec.md specs/$BRANCH/plan.md specs/$BRANCH/tasks.md
```

3. **If diff is empty**: Report "No spec artifact drift detected — artifacts match initial plan."

4. **If diff is non-empty**: For each changed artifact, show a structured summary:
- Sections added / removed / changed (by heading)
- Prompt: "Update [artifact] to reflect implementation changes? (yes/skip)"
- On **yes**: Assist developer in editing the artifact (note: analyze is otherwise read-only,
but user-approved drift corrections are the exception)
- On **skip**: Continue to next artifact

5. **Unresolved task check**: Scan `tasks.md` for unchecked items (`- [ ]`):
```bash
grep -n "^- \[ \]" specs/$BRANCH/tasks.md
```
Cross-reference unchecked tasks with `git log --oneline` for task-related commits.
Flag any tasks with no corresponding commit as:
> "⚠️ Task [TID] has no corresponding commit — possibly unimplemented or not formally
> deferred. Confirm status before marking spec Analyzed."

### 9. Status Advancement

After drift detection and analysis report are complete:
- Update `spec.md` `**Status**:` line → `Analyzed`
- Include this status change in the phase-end commit

### 10. Offer Remediation

Ask the user: "Would you like me to suggest concrete remediation edits for the top N issues?" (Do NOT apply them automatically.)

## Phase-End Commit

1. Run `git status --short` scoped to `specs/$BRANCH/` to check for changes
2. If no changes: report "No changes to commit" and skip
3. If changes exist (analysis report + status advancement): invoke the `conventional-commit` skill with:
- type: `docs`
- scope: `analyze`
- description: `add consistency report for NNN-feature-name`
- footer: issue numbers from spec.md `GitHub Issue` field (e.g., `Refs: #31`)
4. Await developer confirmation before committing (per `conventional-commit` skill workflow)

## Operating Principles

### Context Efficiency
Expand All @@ -173,7 +233,7 @@ Ask the user: "Would you like me to suggest concrete remediation edits for the t

### Analysis Guidelines

- **NEVER modify files** (this is read-only analysis)
- **NEVER modify files** (this is read-only analysis, except user-approved drift corrections)
- **NEVER hallucinate missing sections** (if absent, report them accurately)
- **Prioritize constitution violations** (these are always CRITICAL)
- **Use examples over exhaustive rules** (cite specific instances, not generic patterns)
Expand Down
12 changes: 12 additions & 0 deletions .github/agents/speckit.checklist.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,15 @@ Sample items:
- Correct: Validation of requirement quality
- Wrong: "Does it do X?"
- Correct: "Is X clearly specified?"


## Phase-End Commit

1. Run `git status --short` scoped to `specs/$BRANCH/` to check for changes
2. If no changes: report "No changes to commit" and skip
3. If changes exist: invoke the `conventional-commit` skill with:
- type: `docs`
- scope: `checklist`
- description: `add [domain] checklist for NNN-feature-name`
- footer: issue numbers from spec.md `GitHub Issue` field (e.g., `Refs: #31`)
4. Await developer confirmation before committing (per `conventional-commit` skill workflow)
28 changes: 27 additions & 1 deletion .github/agents/speckit.clarify.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ Note: This clarification workflow is expected to run (and be completed) BEFORE i

Execution steps:

1. Run `.specify/scripts/bash/check-prerequisites.sh --json --paths-only` from repo root **once** (combined `--json --paths-only` mode / `-Json -PathsOnly`). Parse minimal JSON payload fields:
1. **Context Loading** (run at startup before any output):
1. Read `.specify/memory/constitution.md`
2. Read `.specify/memory/stack.md` — if absent, warn: "⚠️ stack.md missing — run `/speckit.specify` first to initialize stack context"
3. Read current spec's `spec.md`
4. Read any existing phase artifacts (`plan.md`) if present
5. Output one-line summary: `Loaded: [spec name] | Status: [status] | Stack: [packaging tool]`

2. Run `.specify/scripts/bash/check-prerequisites.sh --json --paths-only` from repo root **once** (combined `--json --paths-only` mode / `-Json -PathsOnly`). Parse minimal JSON payload fields:
- `FEATURE_DIR`
- `FEATURE_SPEC`
- (Optionally capture `IMPL_PLAN`, `TASKS` for future chained flows.)
Expand Down Expand Up @@ -168,6 +175,25 @@ Execution steps:
- If any Outstanding or Deferred remain, recommend whether to proceed to `/speckit.plan` or run `/speckit.clarify` again later post-plan.
- Suggested next command.

9. **Paradigm Shift Check**: If any clarification answers reveal changes to core architecture
(project type, ORM, packaging tool, authentication model, test framework), surface this before
the phase-end commit:
> "⚠️ Clarification answers indicate a potential stack or architecture change. `.specify/memory/stack.md`
> and/or `.specify/templates/stack-template.md` may need updating. Flag this before proceeding? (yes/skip)"
- On **yes**: note the items in the spec's Assumptions section and add a TODO for the developer
- On **skip**: continue to phase-end commit

10. **Phase-End Commit**:

1. Run `git status --short` scoped to `specs/$BRANCH/` to check for changes
2. If no changes: report "No changes to commit" and skip
3. If changes exist: invoke the `conventional-commit` skill with:
- type: `docs`
- scope: `clarify`
- description: `update NNN-feature-name spec with clarifications`
- footer: issue numbers from spec.md `GitHub Issue` field (e.g., `Refs: #31`)
4. Await developer confirmation before committing (per `conventional-commit` skill workflow)

Behavior rules:

- If no meaningful ambiguities found (or all potential questions would be low-impact), respond: "No critical ambiguities detected worth formal clarification." and suggest proceeding.
Expand Down
Loading
Loading