14 Commits

Author SHA1 Message Date
1166e8c5d3 Fix: Update meta preview images after filename refactor
All checks were successful
Pipeline / UI Lint (push) Successful in 58s
Pipeline / API Unit Tests (push) Successful in 19s
Pipeline / API Lint (push) Successful in 9s
Pipeline / UI Tests (push) Successful in 1m32s
Pipeline / API Integration Tests (push) Successful in 27s
Pipeline / Build & Push API Image (push) Successful in 45s
Pipeline / Build & Push UI Image (push) Successful in 52s
2026-05-12 10:41:05 -04:00
8e94c232b4 Chore: Update spec-kit and install memory-loader extension
All checks were successful
Pipeline / UI Lint (push) Successful in 59s
Pipeline / API Unit Tests (push) Successful in 19s
Pipeline / API Lint (push) Successful in 9s
Pipeline / UI Tests (push) Successful in 1m34s
Pipeline / API Integration Tests (push) Successful in 28s
Pipeline / Build & Push API Image (push) Has been skipped
Pipeline / Build & Push UI Image (push) Has been skipped
2026-05-11 20:55:55 +00:00
b00c52baa3 CI: Remove diagnosis step from integration test job
All checks were successful
Pipeline / UI Lint (push) Successful in 57s
Pipeline / API Unit Tests (push) Successful in 20s
Pipeline / API Lint (push) Successful in 9s
Pipeline / UI Tests (push) Successful in 1m33s
Pipeline / API Integration Tests (push) Successful in 27s
Pipeline / Build & Push API Image (push) Successful in 2m56s
Pipeline / Build & Push UI Image (push) Successful in 3m5s
2026-05-10 19:53:14 -04:00
0dc350d534 CI: Update dummy OWNER_PASSWORD in jobs
All checks were successful
Pipeline / API Lint (push) Successful in 9s
Pipeline / API Integration Tests (push) Successful in 28s
Pipeline / UI Lint (push) Successful in 57s
Pipeline / API Unit Tests (push) Successful in 18s
Pipeline / UI Tests (push) Successful in 1m33s
Pipeline / Build & Push API Image (push) Has been skipped
Pipeline / Build & Push UI Image (push) Has been skipped
2026-05-10 19:51:46 -04:00
ac565e4b85 CI: Shrink dummy JWT secret key 2026-05-10 19:49:36 -04:00
0808e027a5 CI: Extend dummy JWT key to pass test without InsecureKeyLengthWarning
Some checks failed
Pipeline / API Lint (push) Successful in 9s
Pipeline / UI Tests (push) Successful in 1m31s
Pipeline / API Integration Tests (push) Failing after 27s
Pipeline / Build & Push API Image (push) Has been skipped
Pipeline / Build & Push UI Image (push) Has been skipped
Pipeline / UI Lint (push) Successful in 57s
Pipeline / API Unit Tests (push) Successful in 19s
2026-05-10 19:45:59 -04:00
fc48b37ee7 CI: Add diagnosis step to integration test job
Some checks failed
Pipeline / UI Lint (push) Successful in 58s
Pipeline / API Lint (push) Successful in 8s
Pipeline / UI Tests (push) Successful in 1m34s
Pipeline / Build & Push UI Image (push) Has been skipped
Pipeline / API Unit Tests (push) Successful in 19s
Pipeline / API Integration Tests (push) Failing after 26s
Pipeline / Build & Push API Image (push) Has been skipped
2026-05-10 19:36:14 -04:00
026467c6db CI: Add explicit username and database to pg_isready healthcheck
Some checks failed
Pipeline / UI Lint (push) Successful in 58s
Pipeline / API Unit Tests (push) Successful in 19s
Pipeline / API Lint (push) Successful in 9s
Pipeline / UI Tests (push) Successful in 1m33s
Pipeline / API Integration Tests (push) Failing after 43s
Pipeline / Build & Push API Image (push) Has been skipped
Pipeline / Build & Push UI Image (push) Has been skipped
2026-05-10 19:33:16 -04:00
e852c773e7 CI: Use legacy Bitnami images for MinIO
Some checks failed
Pipeline / UI Lint (push) Successful in 58s
Pipeline / API Unit Tests (push) Successful in 19s
Pipeline / API Lint (push) Successful in 9s
Pipeline / UI Tests (push) Successful in 1m31s
Pipeline / API Integration Tests (push) Failing after 46s
Pipeline / Build & Push API Image (push) Has been skipped
Pipeline / Build & Push UI Image (push) Has been skipped
2026-05-10 19:27:28 -04:00
69a4d5a084 CI: Try different approach to running PostgreSQL
Some checks failed
Pipeline / UI Lint (push) Successful in 57s
Pipeline / UI Tests (push) Successful in 1m35s
Pipeline / API Unit Tests (push) Successful in 41s
Pipeline / API Lint (push) Successful in 9s
Pipeline / Build & Push API Image (push) Has been cancelled
Pipeline / Build & Push UI Image (push) Has been cancelled
Pipeline / API Integration Tests (push) Has been cancelled
2026-05-10 19:19:14 -04:00
e13a81e31e CI: Run both Postgres and MinIO with --network container:$(hostname)
The Gitea runner executes jobs inside a container. Port-mapped services
bind to the host VM's interface, not to the runner container's loopback,
so localhost:<port> is always unreachable regardless of services: config.

--network container:$(hostname) joins each service to the job container's
network namespace, making both accessible on localhost. Both DB URL and
S3 endpoint use localhost accordingly.

Also adds timeout-minutes: 15 to bound runaway jobs on cancel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 23:00:46 +00:00
0624795370 CI: Restore Postgres to services, use service name as hostname
Some checks failed
Pipeline / UI Lint (push) Successful in 57s
Pipeline / API Unit Tests (push) Successful in 13s
Pipeline / API Lint (push) Successful in 5s
Pipeline / UI Tests (push) Successful in 1m33s
Pipeline / API Integration Tests (push) Failing after 38s
Pipeline / Build & Push API Image (push) Has been skipped
Pipeline / Build & Push UI Image (push) Has been skipped
Gitea runs jobs in containers, so service containers are networked by
name (same as GitHub Actions with container:). Postgres goes back into
services: and is addressed as 'postgres', not localhost. MinIO stays
as a manual docker run with --network container:$(hostname) since it
needs `server /data` and is addressed as localhost.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 22:54:05 +00:00
e4a77fdea3 CI: Move Postgres to manual docker run with shared network namespace
Service containers bind ports to the host, not to localhost inside the
job container. Start both Postgres and MinIO manually with
--network container:$(hostname) so they share the job container's
network namespace and are reachable on localhost. Use docker exec for
pg_isready to avoid depending on postgresql-client in the runner image.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 22:52:14 +00:00
22e8717e0c Chore: Exclude alembic/ from Ruff linting
Alembic scaffolds migration files from its own template which uses
pre-3.10 conventions (Union[X, Y], typing.Sequence, etc). Excluding
avoids noise on every new migration without affecting app code coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 22:50:05 +00:00
17 changed files with 438 additions and 63 deletions

View File

@@ -65,18 +65,20 @@ jobs:
api-unit: api-unit:
name: API Unit Tests name: API Unit Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: ghcr.io/astral-sh/uv:python3.12-bookworm
steps: steps:
- uses: actions/checkout@v4 - name: Install Node (for JS actions)
- name: Install uv
run: | run: |
curl -LsSf https://astral.sh/uv/install.sh | sh apt-get update -qq
echo "$HOME/.local/bin" >> $GITHUB_PATH apt-get install -y --no-install-recommends nodejs ca-certificates curl
- uses: actions/checkout@v4
- name: Cache uv store - name: Cache uv store
uses: actions/cache@v3 uses: actions/cache@v3
with: with:
path: ~/.cache/uv path: /root/.cache/uv
key: uv-${{ hashFiles('api/uv.lock') }} key: uv-${{ hashFiles('api/uv.lock') }}
restore-keys: uv- restore-keys: uv-
@@ -95,25 +97,32 @@ jobs:
S3_SECRET_ACCESS_KEY: secret S3_SECRET_ACCESS_KEY: secret
S3_REGION: us-east-1 S3_REGION: us-east-1
API_BASE_URL: http://localhost:8000 API_BASE_URL: http://localhost:8000
JWT_SECRET_KEY: test-secret JWT_SECRET_KEY: d34db33fc4f3b00bd34db33fc4f3b00b
OWNER_USERNAME: testowner OWNER_USERNAME: testowner
OWNER_PASSWORD: testpass OWNER_PASSWORD: testpassword
api-lint: api-lint:
name: API Lint name: API Lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: ghcr.io/astral-sh/uv:python3.12-bookworm
steps: steps:
- name: Install Node (for JS actions)
run: |
apt-get update -qq
apt-get install -y --no-install-recommends nodejs ca-certificates curl
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Run Ruff - name: Run Ruff
run: | run: uvx ruff check .
curl -LsSf https://astral.sh/uv/install.sh | sh
~/.local/bin/uvx ruff check .
working-directory: api working-directory: api
api-integration: api-integration:
name: API Integration Tests name: API Integration Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: ghcr.io/astral-sh/uv:python3.12-bookworm
services: services:
postgres: postgres:
image: postgres:16 image: postgres:16
@@ -121,40 +130,34 @@ jobs:
POSTGRES_USER: reactbin POSTGRES_USER: reactbin
POSTGRES_PASSWORD: reactbin POSTGRES_PASSWORD: reactbin
POSTGRES_DB: reactbin_test POSTGRES_DB: reactbin_test
ports:
- 5432:5432
options: >- options: >-
--health-cmd pg_isready --health-cmd "pg_isready -U reactbin -d reactbin_test"
--health-interval 5s
--health-timeout 5s
--health-retries 10
minio:
image: bitnamilegacy/minio:2025.7.23-debian-12-r5
env:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
MINIO_DEFAULT_BUCKETS: reactbin-test
options: >-
--health-cmd "mc ready local || exit 1"
--health-interval 5s --health-interval 5s
--health-timeout 5s --health-timeout 5s
--health-retries 10 --health-retries 10
steps: steps:
- name: Install Node and curl (for JS actions and mc)
run: |
apt-get update -qq
apt-get install -y --no-install-recommends nodejs ca-certificates curl
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Start MinIO
run: |
docker run -d --name ci-minio \
--network container:$(hostname) \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minioadmin \
quay.io/minio/minio server /data
- name: Create MinIO bucket
run: |
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc -o /tmp/mc
chmod +x /tmp/mc
until /tmp/mc alias set local http://localhost:9000 minioadmin minioadmin; do sleep 2; done
/tmp/mc mb local/reactbin-test
- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Cache uv store - name: Cache uv store
uses: actions/cache@v3 uses: actions/cache@v3
with: with:
path: ~/.cache/uv path: /root/.cache/uv
key: uv-${{ hashFiles('api/uv.lock') }} key: uv-${{ hashFiles('api/uv.lock') }}
restore-keys: uv- restore-keys: uv-
@@ -166,21 +169,17 @@ jobs:
run: uv run pytest tests/integration/ -q run: uv run pytest tests/integration/ -q
working-directory: api working-directory: api
env: env:
TEST_DATABASE_URL: postgresql+asyncpg://reactbin:reactbin@localhost/reactbin_test TEST_DATABASE_URL: postgresql+asyncpg://reactbin:reactbin@postgres/reactbin_test
DATABASE_URL: postgresql+asyncpg://reactbin:reactbin@localhost/reactbin_test DATABASE_URL: postgresql+asyncpg://reactbin:reactbin@postgres/reactbin_test
S3_ENDPOINT_URL: http://localhost:9000 S3_ENDPOINT_URL: http://minio:9000
S3_BUCKET_NAME: reactbin-test S3_BUCKET_NAME: reactbin-test
S3_ACCESS_KEY_ID: minioadmin S3_ACCESS_KEY_ID: minioadmin
S3_SECRET_ACCESS_KEY: minioadmin S3_SECRET_ACCESS_KEY: minioadmin
S3_REGION: us-east-1 S3_REGION: us-east-1
API_BASE_URL: http://localhost:8000 API_BASE_URL: http://localhost:8000
JWT_SECRET_KEY: test-secret JWT_SECRET_KEY: d34db33fc4f3b00bd34db33fc4f3b00b
OWNER_USERNAME: testowner OWNER_USERNAME: testowner
OWNER_PASSWORD: testpass OWNER_PASSWORD: testpassword
- name: Stop MinIO
if: always()
run: docker stop ci-minio && docker rm ci-minio || true
# ── Image builds (tag-only, gated on all jobs) ──────────────────────────────── # ── Image builds (tag-only, gated on all jobs) ────────────────────────────────
@@ -232,4 +231,4 @@ jobs:
push: true push: true
tags: | tags: |
${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-ui:${{ github.ref_name }} ${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-ui:${{ github.ref_name }}
${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-ui:latest ${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-ui:latest

View File

@@ -18,6 +18,13 @@ hooks:
prompt: Execute speckit.git.feature? prompt: Execute speckit.git.feature?
description: Create feature branch before specification description: Create feature branch before specification
condition: null condition: null
- extension: memory-loader
command: speckit.memory-loader.load
enabled: true
optional: false
prompt: Execute speckit.memory-loader.load?
description: Load project memory files before specification
condition: null
before_clarify: before_clarify:
- extension: git - extension: git
command: speckit.git.commit command: speckit.git.commit
@@ -26,6 +33,13 @@ hooks:
prompt: Commit outstanding changes before clarification? prompt: Commit outstanding changes before clarification?
description: Auto-commit before spec clarification description: Auto-commit before spec clarification
condition: null condition: null
- extension: memory-loader
command: speckit.memory-loader.load
enabled: true
optional: false
prompt: Execute speckit.memory-loader.load?
description: Load project memory files before clarification
condition: null
before_plan: before_plan:
- extension: git - extension: git
command: speckit.git.commit command: speckit.git.commit
@@ -34,6 +48,13 @@ hooks:
prompt: Commit outstanding changes before planning? prompt: Commit outstanding changes before planning?
description: Auto-commit before implementation planning description: Auto-commit before implementation planning
condition: null condition: null
- extension: memory-loader
command: speckit.memory-loader.load
enabled: true
optional: false
prompt: Execute speckit.memory-loader.load?
description: Load project memory files before planning
condition: null
before_tasks: before_tasks:
- extension: git - extension: git
command: speckit.git.commit command: speckit.git.commit
@@ -42,6 +63,13 @@ hooks:
prompt: Commit outstanding changes before task generation? prompt: Commit outstanding changes before task generation?
description: Auto-commit before task generation description: Auto-commit before task generation
condition: null condition: null
- extension: memory-loader
command: speckit.memory-loader.load
enabled: true
optional: false
prompt: Execute speckit.memory-loader.load?
description: Load project memory files before task generation
condition: null
before_implement: before_implement:
- extension: git - extension: git
command: speckit.git.commit command: speckit.git.commit
@@ -50,6 +78,13 @@ hooks:
prompt: Commit outstanding changes before implementation? prompt: Commit outstanding changes before implementation?
description: Auto-commit before implementation description: Auto-commit before implementation
condition: null condition: null
- extension: memory-loader
command: speckit.memory-loader.load
enabled: true
optional: false
prompt: Execute speckit.memory-loader.load?
description: Load project memory files before implementation
condition: null
before_checklist: before_checklist:
- extension: git - extension: git
command: speckit.git.commit command: speckit.git.commit
@@ -58,6 +93,13 @@ hooks:
prompt: Commit outstanding changes before checklist? prompt: Commit outstanding changes before checklist?
description: Auto-commit before checklist generation description: Auto-commit before checklist generation
condition: null condition: null
- extension: memory-loader
command: speckit.memory-loader.load
enabled: true
optional: false
prompt: Execute speckit.memory-loader.load?
description: Load project memory files before checklist generation
condition: null
before_analyze: before_analyze:
- extension: git - extension: git
command: speckit.git.commit command: speckit.git.commit
@@ -66,6 +108,13 @@ hooks:
prompt: Commit outstanding changes before analysis? prompt: Commit outstanding changes before analysis?
description: Auto-commit before analysis description: Auto-commit before analysis
condition: null condition: null
- extension: memory-loader
command: speckit.memory-loader.load
enabled: true
optional: false
prompt: Execute speckit.memory-loader.load?
description: Load project memory files before analysis
condition: null
before_taskstoissues: before_taskstoissues:
- extension: git - extension: git
command: speckit.git.commit command: speckit.git.commit

View File

@@ -18,6 +18,20 @@
}, },
"registered_skills": [], "registered_skills": [],
"installed_at": "2026-05-02T15:15:14.534434+00:00" "installed_at": "2026-05-02T15:15:14.534434+00:00"
},
"memory-loader": {
"version": "1.0.0",
"source": "local",
"manifest_hash": "sha256:d1caef45965accd4316d8aede0a4ac67f910017ea3c501814cfc7e2d8177ab0b",
"enabled": true,
"priority": 10,
"registered_commands": {
"claude": [
"speckit.memory-loader.load"
]
},
"registered_skills": [],
"installed_at": "2026-05-11T20:50:02.702659+00:00"
} }
} }
} }

View File

@@ -0,0 +1,9 @@
# Changelog
## [1.0.0] - 2026-04-20
### Added
- Initial release
- `speckit.memory-loader.load` command to read all `.specify/memory/*.md` files
- `before_*` hooks for specify, plan, tasks, implement, clarify, checklist, and analyze lifecycle commands
- Graceful degradation when memory directory is missing or files are unreadable

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 KevinBrown5280
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,81 @@
# spec-kit-memory-loader
A [Spec Kit](https://github.com/github/spec-kit) extension that loads `.specify/memory/` files before spec-kit lifecycle commands so LLM agents have project governance context (constitution, glossary, conventions, resource standards).
## Problem
Spec-kit lifecycle commands (`/speckit.specify`, `/speckit.plan`, `/speckit.implement`, etc.) execute without awareness of project-specific governance documents stored in `.specify/memory/`. This means:
- Constitution principles are not consulted during specification
- Glossary terms are not available during planning
- Coding conventions are missed during implementation
- Resource standards are ignored during task generation
## Solution
The Memory Loader extension registers `before_*` hooks on all major spec-kit lifecycle commands. Before each command runs, it reads every `.md` file from `.specify/memory/` and outputs their contents, giving the LLM agent full governance context.
## Installation
```bash
# From release
specify extension add memory-loader --from https://github.com/KevinBrown5280/spec-kit-memory-loader/archive/refs/tags/v1.0.0.zip
# From main branch
specify extension add memory-loader --from https://github.com/KevinBrown5280/spec-kit-memory-loader/archive/refs/heads/main.zip
# Development mode (local clone)
specify extension add --dev /path/to/spec-kit-memory-loader
```
## Commands
| Command | Description | Modifies Files? |
|---------|-------------|-----------------|
| `speckit.memory-loader.load` | Read all project memory files and output their contents for context | No — read-only |
## How It Works
1. **Gather**: Reads every `.md` file from `.specify/memory/`
- If the directory does not exist, skips silently
- If a file cannot be read, skips it and continues
2. **Output**: For each file, prints a headed section:
```
## Memory: {filename}
{file contents}
```
3. **Summarize**: After all files, outputs:
```
Context loaded: {memory_count} memory files
```
## Hooks
The extension fires automatically before these lifecycle commands:
| Hook | Command | Description |
|------|---------|-------------|
| `before_specify` | `speckit.memory-loader.load` | Load context before specification |
| `before_plan` | `speckit.memory-loader.load` | Load context before planning |
| `before_tasks` | `speckit.memory-loader.load` | Load context before task generation |
| `before_implement` | `speckit.memory-loader.load` | Load context before implementation |
| `before_clarify` | `speckit.memory-loader.load` | Load context before clarification |
| `before_checklist` | `speckit.memory-loader.load` | Load context before checklist generation |
| `before_analyze` | `speckit.memory-loader.load` | Load context before analysis |
## Design Decisions
- **Read-only** — never modifies any files
- **Graceful degradation** — missing directory or unreadable files are skipped silently
- **Governance only** — loads project-level memory; feature-specific reference docs are handled separately by a companion extension
## Requirements
- Spec Kit >= 0.6.0
## License
MIT

View File

@@ -0,0 +1,33 @@
---
description: "Read all project memory files and output their contents for LLM context"
---
# Load Project Memory
Read ALL `.md` files in `.specify/memory/` and output their contents. This gives you project governance context (constitution, glossary, conventions, resource standards) for the command that follows.
## Steps
1. **Gather**: Read every `.md` file from `.specify/memory/`.
- If the directory does not exist, skip it silently.
- If a file cannot be read, skip it and continue.
2. **Output**: For each file, print a headed section:
```
## Memory: {filename}
{file contents}
```
3. **Summarize**: After all files, output:
```
Context loaded: {memory_count} memory files
```
## Usage Notes
- Designed as a mandatory `before_*` hook that fires before spec-kit lifecycle commands.
- Loads governance context only. Feature-specific reference docs are loaded by the `spec-reference-loader` extension.
- This is a read-only operation — do NOT modify any files.

View File

@@ -0,0 +1,61 @@
schema_version: "1.0"
extension:
id: "memory-loader"
name: "Memory Loader"
version: "1.0.0"
description: "Loads .specify/memory/ files before spec-kit lifecycle commands so LLM agents have project governance context"
author: "KevinBrown5280"
repository: "https://github.com/KevinBrown5280/spec-kit-memory-loader"
license: "MIT"
homepage: "https://github.com/KevinBrown5280/spec-kit-memory-loader"
requires:
speckit_version: ">=0.6.0"
provides:
commands:
- name: "speckit.memory-loader.load"
file: "commands/speckit.memory-loader.load.md"
description: "Read all project memory files and output their contents for context"
hooks:
before_specify:
command: "speckit.memory-loader.load"
optional: false
description: "Load project memory files before specification"
before_plan:
command: "speckit.memory-loader.load"
optional: false
description: "Load project memory files before planning"
before_tasks:
command: "speckit.memory-loader.load"
optional: false
description: "Load project memory files before task generation"
before_implement:
command: "speckit.memory-loader.load"
optional: false
description: "Load project memory files before implementation"
before_clarify:
command: "speckit.memory-loader.load"
optional: false
description: "Load project memory files before clarification"
before_checklist:
command: "speckit.memory-loader.load"
optional: false
description: "Load project memory files before checklist generation"
before_analyze:
command: "speckit.memory-loader.load"
optional: false
description: "Load project memory files before analysis"
tags:
- "memory"
- "context"
- "governance"

View File

@@ -6,5 +6,5 @@
"here": true, "here": true,
"integration": "claude", "integration": "claude",
"script": "sh", "script": "sh",
"speckit_version": "0.8.2.dev0" "speckit_version": "0.8.8"
} }

View File

@@ -1,4 +1,15 @@
{ {
"version": "0.8.8",
"integration_state_schema": 1,
"installed_integrations": [
"claude"
],
"integration_settings": {
"claude": {
"script": "sh",
"invoke_separator": "-"
}
},
"integration": "claude", "integration": "claude",
"version": "0.8.2.dev0" "default_integration": "claude"
} }

View File

@@ -1,16 +1,16 @@
{ {
"integration": "claude", "integration": "claude",
"version": "0.8.2.dev0", "version": "0.8.8",
"installed_at": "2026-05-02T15:15:14.461699+00:00", "installed_at": "2026-05-11T20:40:51.902830+00:00",
"files": { "files": {
".claude/skills/speckit-analyze/SKILL.md": "2eef0fbff6cad15c9d4714d8986192387811c971a82a1135ab0404f3db0c5e90", ".claude/skills/speckit-analyze/SKILL.md": "2eef0fbff6cad15c9d4714d8986192387811c971a82a1135ab0404f3db0c5e90",
".claude/skills/speckit-checklist/SKILL.md": "26419fc118dcd9c4e1e977460696a04b7757b8fb0a2d1ff9c64732669deb7977", ".claude/skills/speckit-checklist/SKILL.md": "26419fc118dcd9c4e1e977460696a04b7757b8fb0a2d1ff9c64732669deb7977",
".claude/skills/speckit-clarify/SKILL.md": "f2560f9f2007b4e995130f0c42633f08837a76a35d94e84091713a6f39bb1064", ".claude/skills/speckit-clarify/SKILL.md": "f2560f9f2007b4e995130f0c42633f08837a76a35d94e84091713a6f39bb1064",
".claude/skills/speckit-constitution/SKILL.md": "c1a044aba243ca6aff627fb5e4404feb6f1108d4f7dd174631bee3ae477d6c15", ".claude/skills/speckit-constitution/SKILL.md": "c1a044aba243ca6aff627fb5e4404feb6f1108d4f7dd174631bee3ae477d6c15",
".claude/skills/speckit-implement/SKILL.md": "da9b4d6f9894d300515c66c057cee74025b27f2238895e3c22b59c6266b5be74", ".claude/skills/speckit-implement/SKILL.md": "6029565c1a56de8919d1846b187cd644f734a0e30a6067a709803e6bc0d2abf7",
".claude/skills/speckit-plan/SKILL.md": "8141ebbce228ad0b422a84e3b995d2bd85de917b96eadd02b5fcb56fb23f2594", ".claude/skills/speckit-plan/SKILL.md": "8141ebbce228ad0b422a84e3b995d2bd85de917b96eadd02b5fcb56fb23f2594",
".claude/skills/speckit-specify/SKILL.md": "8599f8e2e3463de7d4f47591565340be2f775fd61b7dd9d2175503bc3b713b77", ".claude/skills/speckit-specify/SKILL.md": "caadc05119eca453709a0425ed88d253883f9c55da4c13a4898367653a859483",
".claude/skills/speckit-tasks/SKILL.md": "792589edf0ebf89af797c6bdda4e9d2c9938c696181d6f1484bf7a7cd090efaa", ".claude/skills/speckit-tasks/SKILL.md": "54c4665be61818ed50aa528bb4c51db3627079b2c67d47f2b01046268288c4a5",
".claude/skills/speckit-taskstoissues/SKILL.md": "99bf5ffd90dcb57b63007c7f659a5160a18ce6feb82889895808e2d277abe83b" ".claude/skills/speckit-taskstoissues/SKILL.md": "99bf5ffd90dcb57b63007c7f659a5160a18ce6feb82889895808e2d277abe83b"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"integration": "speckit", "integration": "speckit",
"version": "0.8.2.dev0", "version": "0.8.8",
"installed_at": "2026-05-02T15:15:14.478105+00:00", "installed_at": "2026-05-02T15:15:14.478105+00:00",
"files": { "files": {
".specify/scripts/bash/create-new-feature.sh": "bcf4964ca0c6c78717bb42d9e66b8c7e5ee82779cd96afc5aa7b08b75abe5790", ".specify/scripts/bash/create-new-feature.sh": "bcf4964ca0c6c78717bb42d9e66b8c7e5ee82779cd96afc5aa7b08b75abe5790",
@@ -11,6 +11,7 @@
".specify/templates/plan-template.md": "5ad267630e370c73fe957dafa61bf76d633f3aea9d2f0b5195087d729cdd1e41", ".specify/templates/plan-template.md": "5ad267630e370c73fe957dafa61bf76d633f3aea9d2f0b5195087d729cdd1e41",
".specify/templates/constitution-template.md": "ce7549540fa45543cca797a150201d868e64495fdff39dc38246fb17bd4024b3", ".specify/templates/constitution-template.md": "ce7549540fa45543cca797a150201d868e64495fdff39dc38246fb17bd4024b3",
".specify/templates/spec-template.md": "785dc50d856dd92d6515eca0761e16dce0c9ba0a3cd07154fd33eae77932422a", ".specify/templates/spec-template.md": "785dc50d856dd92d6515eca0761e16dce0c9ba0a3cd07154fd33eae77932422a",
".specify/templates/checklist-template.md": "c37695297e5d3153d64f82c21223509940b13932046c7961c42d1d669516130c" ".specify/templates/checklist-template.md": "c37695297e5d3153d64f82c21223509940b13932046c7961c42d1d669516130c",
".specify/scripts/bash/setup-tasks.sh": "e8d050c63c5afb664a8b671b0b0155513fb9cab0567b335e16b9eb035482aad2"
} }
} }

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env bash
set -e
# Parse command line arguments
JSON_MODE=false
for arg in "$@"; do
case "$arg" in
--json) JSON_MODE=true ;;
--help|-h)
echo "Usage: $0 [--json]"
echo " --json Output results in JSON format"
echo " --help Show this help message"
exit 0
;;
*) echo "ERROR: Unknown option '$arg'" >&2; exit 1 ;;
esac
done
# Source common functions
SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"
# Get feature paths
_paths_output=$(get_feature_paths) || { echo "ERROR: Failed to resolve feature paths" >&2; exit 1; }
eval "$_paths_output"
unset _paths_output
# Validate branch
# If feature.json pins an existing feature directory, branch naming is not required.
if ! feature_json_matches_feature_dir "$REPO_ROOT" "$FEATURE_DIR"; then
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
fi
if [[ ! -f "$IMPL_PLAN" ]]; then
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
echo "Run /speckit.plan first to create the implementation plan." >&2
exit 1
fi
if [[ ! -f "$FEATURE_SPEC" ]]; then
echo "ERROR: spec.md not found in $FEATURE_DIR" >&2
echo "Run /speckit.specify first to create the feature structure." >&2
exit 1
fi
# Build available docs list
docs=()
[[ -f "$RESEARCH" ]] && docs+=("research.md")
[[ -f "$DATA_MODEL" ]] && docs+=("data-model.md")
if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then
docs+=("contracts/")
fi
[[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")
# Resolve tasks template through override stack
TASKS_TEMPLATE=$(resolve_template "tasks-template" "$REPO_ROOT") || true
if [[ -z "$TASKS_TEMPLATE" ]] || [[ ! -f "$TASKS_TEMPLATE" ]]; then
echo "ERROR: Could not resolve required tasks-template from the template override stack for $REPO_ROOT" >&2
echo "Template 'tasks-template' was not found in any supported location (overrides, presets, extensions, or shared core). Add an override at .specify/templates/overrides/tasks-template.md, or run 'specify init' / reinstall shared infra to restore the core .specify/templates/tasks-template.md template." >&2
exit 1
fi
# Output results
if $JSON_MODE; then
if has_jq; then
if [[ ${#docs[@]} -eq 0 ]]; then
json_docs="[]"
else
json_docs=$(printf '%s\n' "${docs[@]}" | jq -R . | jq -s .)
fi
jq -cn \
--arg feature_dir "$FEATURE_DIR" \
--argjson docs "$json_docs" \
--arg tasks_template "${TASKS_TEMPLATE:-}" \
'{FEATURE_DIR:$feature_dir,AVAILABLE_DOCS:$docs,TASKS_TEMPLATE:$tasks_template}'
else
if [[ ${#docs[@]} -eq 0 ]]; then
json_docs="[]"
else
json_docs=$(for d in "${docs[@]}"; do printf '"%s",' "$(json_escape "$d")"; done)
json_docs="[${json_docs%,}]"
fi
printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s,"TASKS_TEMPLATE":"%s"}\n' \
"$(json_escape "$FEATURE_DIR")" "$json_docs" "$(json_escape "${TASKS_TEMPLATE:-}")"
fi
else
echo "FEATURE_DIR: $FEATURE_DIR"
echo "TASKS_TEMPLATE: ${TASKS_TEMPLATE:-not found}"
echo "AVAILABLE_DOCS:"
check_file "$RESEARCH" "research.md"
check_file "$DATA_MODEL" "data-model.md"
check_dir "$CONTRACTS_DIR" "contracts/"
check_file "$QUICKSTART" "quickstart.md"
fi

View File

@@ -8,7 +8,7 @@ description: "Task list template for feature implementation"
**Input**: Design documents from `/specs/[###-feature-name]/` **Input**: Design documents from `/specs/[###-feature-name]/`
**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/ **Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/
**Tests**: The examples below include test tasks. Per §5.1 of the constitution, TDD is non-negotiable — test tasks MUST appear before every implementation task. The test task labels below marked "OPTIONAL" refer to the *type* of test (E2E is best-effort per §5.2), not whether tests are written at all. **Tests**: The examples below include test tasks. Tests are OPTIONAL - only include them if explicitly requested in the feature specification.
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story. **Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
@@ -79,7 +79,7 @@ Examples of foundational tasks (adjust based on your project):
**Independent Test**: [How to verify this story works on its own] **Independent Test**: [How to verify this story works on its own]
### Tests for User Story 1 (REQUIRED per §5.1 — TDD) ⚠️ ### Tests for User Story 1 (OPTIONAL - only if tests requested) ⚠️
> **NOTE: Write these tests FIRST, ensure they FAIL before implementation** > **NOTE: Write these tests FIRST, ensure they FAIL before implementation**
@@ -105,7 +105,7 @@ Examples of foundational tasks (adjust based on your project):
**Independent Test**: [How to verify this story works on its own] **Independent Test**: [How to verify this story works on its own]
### Tests for User Story 2 (REQUIRED per §5.1 — TDD) ⚠️ ### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️
- [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py - [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py - [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py
@@ -127,7 +127,7 @@ Examples of foundational tasks (adjust based on your project):
**Independent Test**: [How to verify this story works on its own] **Independent Test**: [How to verify this story works on its own]
### Tests for User Story 3 (REQUIRED per §5.1 — TDD) ⚠️ ### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️
- [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py - [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py - [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py
@@ -198,7 +198,7 @@ Examples of foundational tasks (adjust based on your project):
## Parallel Example: User Story 1 ## Parallel Example: User Story 1
```bash ```bash
# Launch all tests for User Story 1 together (TDD — write before implementation): # Launch all tests for User Story 1 together (if tests requested):
Task: "Contract test for [endpoint] in tests/contract/test_[name].py" Task: "Contract test for [endpoint] in tests/contract/test_[name].py"
Task: "Integration test for [user journey] in tests/integration/test_[name].py" Task: "Integration test for [user journey] in tests/integration/test_[name].py"

View File

@@ -1,5 +1,4 @@
<!-- SPECKIT START --> <!-- SPECKIT START -->
For additional context about technologies to be used, project structure, For additional context about technologies to be used, project structure,
shell commands, and other important information, read the current plan at shell commands, and other important information, read the current plan
`specs/018-pagination-controls/plan.md`.
<!-- SPECKIT END --> <!-- SPECKIT END -->

View File

@@ -30,6 +30,7 @@ dev = [
[tool.ruff] [tool.ruff]
line-length = 100 line-length = 100
target-version = "py312" target-version = "py312"
exclude = ["alembic/"]
[tool.ruff.lint] [tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM"] select = ["E", "F", "I", "UP", "B", "SIM"]

View File

@@ -10,12 +10,12 @@
<meta property="og:title" content="Reactbin"> <meta property="og:title" content="Reactbin">
<meta property="og:description" content="Find your perfect reaction image."> <meta property="og:description" content="Find your perfect reaction image.">
<meta property="og:url" content="https://reactbin.juggalol.com"> <meta property="og:url" content="https://reactbin.juggalol.com">
<meta property="og:image" content="https://cdn.reactbin.juggalol.com/0bdaf046f534a1c913629d7ce8069ce407898c19794527bf842524ff4c0073de"> <meta property="og:image" content="https://cdn.reactbin.juggalol.com/WYMmXnpA">
<!-- Twitter Card --> <!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Reactbin"> <meta name="twitter:title" content="Reactbin">
<meta name="twitter:description" content="Find your perfect reaction image."> <meta name="twitter:description" content="Find your perfect reaction image.">
<meta name="twitter:image" content="https://cdn.reactbin.juggalol.com/0bdaf046f534a1c913629d7ce8069ce407898c19794527bf842524ff4c0073de"> <meta name="twitter:image" content="https://cdn.reactbin.juggalol.com/WYMmXnpA">
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">